基于qwertySearch和T9Search實(shí)現(xiàn)的通訊錄Demo

  • 先上效果圖
通訊錄.gif
  • 實(shí)現(xiàn)思路

    1. 異步加載聯(lián)系人
     ```java
    private List<BeanContact> getBaseContactList(Context context) {
      List<BeanContact> kanjiStartBeanContact = new ArrayList<BeanContact>();
      HashMap<String, BeanContact> kanjiStartBeanContactHashMap = new HashMap<String, BeanContact>();
      List<BeanContact> nonKanjiStartBeanContact = new ArrayList<BeanContact>();
      HashMap<String, BeanContact> nonKanjiStartBeanContactHashMap = new HashMap<String, BeanContact>();
      List<BeanContact> beanContactList = new ArrayList<BeanContact>();
      BeanContact cs = null;
      Cursor cursor = null;
      String sortkey = null;
      long startLoadTime = System.currentTimeMillis();
      String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
      try {
          cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, "sort_key");
          int idColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
          int dispalyNameColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
          int numberColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
          while (cursor.moveToNext()) {
              String id = cursor.getString(idColumnIndex);
              String displayName = cursor.getString(dispalyNameColumnIndex);
              String phoneNumber = cursor.getString(numberColumnIndex);
              boolean kanjiStartBeanContactExist = kanjiStartBeanContactHashMap.containsKey(id);
              boolean nonKanjiStartBeanContactExist = nonKanjiStartBeanContactHashMap.containsKey(id);
              if (true == kanjiStartBeanContactExist) {
                  cs = kanjiStartBeanContactHashMap.get(id);
                  cs.addMultipleContact(cs, phoneNumber);
              } else if (true == nonKanjiStartBeanContactExist) {
                  cs = nonKanjiStartBeanContactHashMap.get(id);
                  cs.addMultipleContact(cs, phoneNumber);
              } else {
                  cs = new BeanContact(id, displayName, phoneNumber);
                  PinyinUtil.parse(cs.getmNamePinyinSearchUnit());
                  sortkey = PinyinUtil.getSortKey(cs.getmNamePinyinSearchUnit()).toUpperCase();
                  cs.setmSortKey(praseSortKey(sortkey));
                  boolean isKanji = PinyinUtil.isKanji(cs.getmName().charAt(0));
                  if (true == isKanji) {
                      kanjiStartBeanContactHashMap.put(id, cs);
                  } else {
                      nonKanjiStartBeanContactHashMap.put(id, cs);
                  }
              }
          }
      } catch (Exception e) {
          e.printStackTrace();
      } finally {
          if (null != cursor) {
              cursor.close();
              cursor = null;
          }
      }
      kanjiStartBeanContact.addAll(kanjiStartBeanContactHashMap.values());
      Collections.sort(kanjiStartBeanContact, BeanContact.mAscComparator);
      nonKanjiStartBeanContact.addAll(nonKanjiStartBeanContactHashMap.values());
      Collections.sort(nonKanjiStartBeanContact, BeanContact.mAscComparator);
      beanContactList.addAll(kanjiStartBeanContact);
      //merge nonKanjiStartBeanContact and kanjiStartBeanContact
      int lastIndex = 0;
      boolean shouldBeAdd = false;
      for (int i = 0; i < nonKanjiStartBeanContact.size(); i++) {
          String nonKanfirstLetter = PinyinUtil.getFirstLetter(nonKanjiStartBeanContact.get(i).getmNamePinyinSearchUnit());
          int j = 0;
          for (j = 0 + lastIndex; j < beanContactList.size(); j++) {
              String firstLetter = PinyinUtil.getFirstLetter(beanContactList.get(j).getmNamePinyinSearchUnit());
              lastIndex++;
              if (firstLetter.charAt(0) > nonKanfirstLetter.charAt(0)) {
                  shouldBeAdd = true;
                  break;
              } else {
                  shouldBeAdd = false;
              }
          }
          if (lastIndex >= beanContactList.size()) {
              lastIndex++;
              shouldBeAdd = true;
          }
          if (true == shouldBeAdd) {
              beanContactList.add(j, nonKanjiStartBeanContact.get(i));
              shouldBeAdd = false;
          }
      }
      long endLoadTime = System.currentTimeMillis();
      Log.i(TAG, "endLoadTime-startLoadTime=[" + (endLoadTime - startLoadTime) + "] BeanContact.size()=" + beanContactList.size());
      return beanContactList;
    

    }
    ```
    2 . 解析基礎(chǔ)聯(lián)系人list生成Map用于映射26個(gè)英文字母和對(duì)應(yīng)的聯(lián)系人list,這樣就可以實(shí)現(xiàn)這種效果用于更精準(zhǔn)定位聯(lián)系人

精準(zhǔn)定位聯(lián)系人.png
 public class ContactIndexHelper {

 private HashMap<String, List<BeanContact>> hashMap;//映射對(duì)應(yīng)字母的聯(lián)系人集合
 private static ContactIndexHelper helper;

 public HashMap<String, List<BeanContact>> getHashMap() {
     return hashMap;
 }

 public void setHashMap(HashMap<String, List<BeanContact>> hashMap) {
     this.hashMap = hashMap;
 }

 private ContactIndexHelper() {
     hashMap = new HashMap<>();
     for (int i = 0; i < QuickAlphabeticBar.getSelectCharacters().length; i++) {
         hashMap.put(String.valueOf(QuickAlphabeticBar.getSelectCharacters()[i]), new ArrayList<BeanContact>());
     }
 }

 public static ContactIndexHelper getInstance() {
     if (helper == null) {
         helper = new ContactIndexHelper();
     }
     return helper;
 }

 public void parseContact(List<BeanContact> list) {
     for (int i = 0; i < list.size(); i++) {
         hashMap.get(String.valueOf(list.get(i).getmSortKey().charAt(0))).add(list.get(i));
     }
 }
}
//當(dāng)滑動(dòng)右側(cè)quickBar的時(shí)候根據(jù)手指滑動(dòng)到的字母獲取到對(duì)應(yīng)的聯(lián)系人集合硅急,然后再次進(jìn)行過濾獲取不重復(fù)的聯(lián)系人
public void updateUi(String letter) {
     textView.setText(letter);
     List<BeanContact> tempList = ContactIndexHelper.getInstance().getHashMap().get(letter);//獲取對(duì)應(yīng)字母的聯(lián)系人集合
     List<BeanContact> resultList = new ArrayList<>();
     if (tempList.size() > 0 && tempList.get(0) != null) {
         resultList.add(tempList.get(0));
     }
     for (int i = 1; i < tempList.size(); i++) {//過濾這個(gè)聯(lián)系人list广恢,得到姓不重復(fù)的新聯(lián)系人list
         if (!String.valueOf(tempList.get(i).getmName().charAt(0)).equalsIgnoreCase(String.valueOf(tempList.get(i - 1).getmName().charAt(0)))) {
             resultList.add(tempList.get(i));
         }
     }
     quickAdapter.clear();
     quickAdapter.addAll(resultList);
 }
   ```
3 . 自定義右側(cè)qucikBar
```java
 public class QuickAlphabeticBar extends View {
 private static final String TAG = "QuickAlphabeticBar";
 public static final char DEFAULT_INDEX_CHARACTER = '#';
 private static char[] mSelectCharacters = {DEFAULT_INDEX_CHARACTER, 'A',
         'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
         'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

 private SectionIndexer mSectionIndexer;
 private ListView mQuickAlphabeticLv;
 private TextView mSelectCharTv;

 private char mCurrentSelectChar;
 private OnQuickAlphabeticBar onQuickAlphabeticBar;

 interface OnQuickAlphabeticBar {
     abstract void onTouchDown();//手指按下

     abstract void onTouchUp();//手指抬起
 }

 public OnQuickAlphabeticBar getOnQuickAlphabeticBar() {
     return onQuickAlphabeticBar;
 }

 public void setOnQuickAlphabeticBar(OnQuickAlphabeticBar onQuickAlphabeticBar) {
     this.onQuickAlphabeticBar = onQuickAlphabeticBar;
 }

 public QuickAlphabeticBar(Context context, AttributeSet attrs) {
     super(context, attrs);
 }

 public static char[] getSelectCharacters() {
     return mSelectCharacters;
 }

 /*public static void setSelectCharacters(char[] mSelectCharacters) {
     QuickAlphabeticBar.mSelectCharacters = mSelectCharacters;
 }*/

 public SectionIndexer getSectionIndexer() {
     return mSectionIndexer;
 }

 public void setSectionIndexer(SectionIndexer sectionIndexer) {
     mSectionIndexer = sectionIndexer;
 }

 public ListView getQuickAlphabeticLv() {
     return mQuickAlphabeticLv;
 }

 public void setQuickAlphabeticLv(ListView quickAlphabeticLv) {
     mQuickAlphabeticLv = quickAlphabeticLv;
 }

 public TextView getSelectCharTv() {
     return mSelectCharTv;
 }

 public void setSelectCharTv(TextView selectCharTv) {
     mSelectCharTv = selectCharTv;
 }

 public char getCurrentSelectChar() {
     return mCurrentSelectChar;
 }

 public void setCurrentSelectChar(char currentSelectChar) {
     mCurrentSelectChar = currentSelectChar;
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
     super.onTouchEvent(event);
     int index = getCurrentIndex(event);
     //Log.i(TAG,"index="+index);
     if ((event.getAction() == MotionEvent.ACTION_DOWN) || (event.getAction() == MotionEvent.ACTION_MOVE)) {
         setBackgroundColor(ContextCompat.getColor(getContext(), R.color.gray));
         //reference: http://blog.csdn.net/jack_l1/article/details/14165291
         if (null != mSectionIndexer) {
             int position = mSectionIndexer.getPositionForSection(mSelectCharacters[index]);
             if (position < 0) {
                 return true;
             }
             if (null != mSelectCharTv) {    //show select char
                 mSelectCharTv.setVisibility(View.VISIBLE);
                 mSelectCharTv.setText(String.valueOf(mSelectCharacters[index]));
             }
             if (null != mQuickAlphabeticLv) {
                 mQuickAlphabeticLv.setSelection(position);
             }
             if (onQuickAlphabeticBar != null) {
                 onQuickAlphabeticBar.onTouchDown();
             }
         }
     } else if (event.getAction() == MotionEvent.ACTION_UP) {
         setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
         if (null != mSelectCharTv) {    //hide select char
             mSelectCharTv.setVisibility(View.GONE);
         }
         if (onQuickAlphabeticBar != null) {
             onQuickAlphabeticBar.onTouchUp();
         }
     }
     return true;
 }

 @Override
 protected void onDraw(Canvas canvas) {
     float xPos = getMeasuredWidth() / 2;
     float yPos = 0;
     if (mSelectCharacters.length > 0) {
         float sigleHeight = getMeasuredHeight() / mSelectCharacters.length;
         for (int i = 0; i < mSelectCharacters.length; i++) {
             yPos = (i + 1) * sigleHeight;
             if (mSelectCharacters[i] == mCurrentSelectChar) {
                 RectF rectF = new RectF(xPos - sigleHeight / 3, yPos - sigleHeight / 3, xPos + sigleHeight / 3, yPos + sigleHeight / 3);
                 canvas.drawRect(rectF, mBluePaint);
                 Paint.FontMetricsInt fontMetrics = mCurrentIndexPaint.getFontMetricsInt();
                 // 轉(zhuǎn)載請(qǐng)注明出處:http://blog.csdn.net/hursing
                 int baseline = ((int) rectF.bottom + (int) rectF.top - fontMetrics.bottom - fontMetrics.top) / 2;//讓文字豎直居中可以看下textview源碼
                 canvas.drawText(String.valueOf(mSelectCharacters[i]), rectF.centerX(), baseline, mCurrentIndexPaint);
             } else {
                 RectF rectF = new RectF(xPos - sigleHeight / 3, yPos - sigleHeight / 3, xPos + sigleHeight / 3, yPos + sigleHeight / 3);
                 Paint.FontMetricsInt fontMetrics = mCurrentIndexPaint.getFontMetricsInt();
                 int baseline = ((int) rectF.bottom + (int) rectF.top - fontMetrics.bottom - fontMetrics.top) / 2;
                 canvas.drawText(String.valueOf(mSelectCharacters[i]), rectF.centerX(), baseline, mOtherIndexPaint);
             }
         }
     }
     super.onDraw(canvas);
 }

 private int getCurrentIndex(MotionEvent event) {
     if (null == event) {
         return 0;
     }

     int y = (int) event.getY();
     int index = y / (getMeasuredHeight() / mSelectCharacters.length);
     if (index < 0) {
         index = 0;
     } else if (index >= mSelectCharacters.length) {
         index = mSelectCharacters.length - 1;
     }

     return index;
 }

 private Paint mCurrentIndexPaint = new Paint();

 {
     mCurrentIndexPaint.setColor(Color.WHITE);
     mCurrentIndexPaint.setTextSize(24);
     mCurrentIndexPaint.setTypeface(Typeface.DEFAULT_BOLD);
     mCurrentIndexPaint.setTextAlign(Paint.Align.CENTER);
 }

 private Paint mBluePaint = new Paint();

 {
     mBluePaint.setColor(ContextCompat.getColor(getContext(), R.color.blue2));
 }

 private Paint mOtherIndexPaint = new Paint();

 {
     mOtherIndexPaint.setColor(Color.BLACK);
     mOtherIndexPaint.setTextSize(24);
     mOtherIndexPaint.setTypeface(Typeface.DEFAULT_BOLD);
     mOtherIndexPaint.setTextAlign(Paint.Align.CENTER);
   }
   }

4 .qwertySearch和T9Search 分別用于聯(lián)系人頁的搜索和撥號(hào)頁的撥號(hào)盤搜索

         public List<BeanContact> qwertySearch(String keyword) {
           List<BeanContact> mSearchContacts = new ArrayList<BeanContact>();
           if (TextUtils.isEmpty(keyword)) {// add all base data to search
           for (int i = 0; i < mBaseContactList.size(); i++) {
             BeanContact currentContacts = null;
             for (currentContacts = mBaseContactList.get(i); null != currentContacts; currentContacts                   = currentContacts.getmNextContacts()) {
                 currentContacts.setSearchByType(BeanContact.SearchByType.SearchByNull);
                 currentContacts.setmMatchKeywords("");
                 if (true == currentContacts.ismFirstMultipleContacts()) {
                     mSearchContacts.add(currentContacts);
                 } else {
                     if (false == currentContacts.ismHideMultipleContacts()) {
                         mSearchContacts.add(currentContacts);
                     }
                 }
             }
         }
         return mSearchContacts;
         }
         int contactsCount = mBaseContactList.size();
         /**
          * search process: 1:Search by name (1)Search by original name (2)Search
          * by name pinyin characters(original name->name pinyin characters)
          * 2:Search by phone number
          */
         for (int i = 0; i < contactsCount; i++) {
             PinyinSearchUnit namePinyinSearchUnit = mBaseContactList.get(i).getmNamePinyinSearchUnit();
             if (true == QwertyUtil.match(namePinyinSearchUnit, keyword)) {// search by name;
             BeanContact currentContacts = null;
             currentContacts = mBaseContactList.get(i);
             currentContacts.setSearchByType(BeanContact.SearchByType.SearchByName);
             currentContacts.setmMatchKeywords(namePinyinSearchUnit.getMatchKeyword().toString());
             mSearchContacts.add(currentContacts);
             continue;
             } else {
             BeanContact currentContacts = null;
             for (currentContacts = mBaseContactList.get(i); null != currentContacts; currentContacts = currentContacts.getmNextContacts()) {
                 if (currentContacts.getmPhoneNumber().contains(keyword)) {// search by phone number
                     currentContacts.setSearchByType(BeanContact.SearchByType.SearchByPhoneNumber);
                     currentContacts.setmMatchKeywords(keyword);
                     mSearchContacts.add(currentContacts);
                 }
             }
             continue;
           }
         }
         if (mSearchContacts.size() <= 0) {
         } else {
         Collections.sort(mSearchContacts, BeanContact.mAscComparator);
         }
         return mSearchContacts;
         }

    public List<BeanContact> t9InputSearch(String keyword) {
       List<BeanContact> mSearchByNameContacts = new ArrayList<BeanContact>();
       List<BeanContact> mSearchByPhoneNumberContacts = new ArrayList<BeanContact>();
       List<BeanContact> mSearchContacts = new ArrayList<BeanContact>();
       if (null == keyword) {// add all base data to search
         return mSearchContacts;
       }
       int contactsCount = mBaseContactList.size();

     /**
      * search process: 1:Search by name (1)Search by name pinyin
      * characters(org name->name pinyin characters) ('0'~'9','*','#')
      * (2)Search by org name ('0'~'9','*','#') 2:Search by phone number
      * ('0'~'9','*','#')
      */
     for (int i = 0; i < contactsCount; i++) {
         PinyinSearchUnit namePinyinSearchUnit = mBaseContactList.get(i).getmNamePinyinSearchUnit();
         if (true == T9Util.match(namePinyinSearchUnit, keyword)) {// search by name;
             BeanContact currentContacts = null;
             currentContacts = mBaseContactList.get(i);
//                currentContacts.setSearchByType(BeanContact.SearchByType.SearchByName);
             currentContacts.setmMatchT9Keywords(namePinyinSearchUnit.getMatchKeyword().toString());
             mSearchByNameContacts.add(currentContacts);
//                BeanContact firstContacts = null;
//                for (currentContacts = mBaseContactList.get(i), firstContacts = currentContacts; null != currentContacts; currentContacts = currentContacts.getmNextContacts()) {
//                    currentContacts.setSearchByType(BeanContact.SearchByType.SearchByName);
//                    currentContacts.setmMatchKeywords(namePinyinSearchUnit.getMatchKeyword().toString());
////                    currentContacts.setMatchStartIndex(firstContacts.getName().indexOf(firstContacts.getMatchKeywords().toString()));
////                    currentContacts.setMatchLength(firstContacts.getMatchKeywords().length());
//                    mSearchByNameContacts.add(currentContacts);
//                }

             continue;
         } else {
             BeanContact currentContacts = null;
             for (currentContacts = mBaseContactList.get(i); null != currentContacts; currentContacts = currentContacts.getmNextContacts()) {
                 if (currentContacts.getmPhoneNumber().contains(keyword)) {// search by phone number
//                        currentContacts.setSearchByType(BeanContact.SearchByType.SearchByPhoneNumber);
                     currentContacts.setmMatchT9Keywords(keyword);
//                        currentContacts.setMatchStartIndex(currentContacts.getPhoneNumber().indexOf(keyword));
//                        currentContacts.setMatchLength(keyword.length());
                     mSearchByPhoneNumberContacts.add(currentContacts);
                 }
             }
             continue;
         }
     }
     if (mSearchByNameContacts.size() > 0) {
         Collections.sort(mSearchByNameContacts, BeanContact.mAscComparator);
     }
     if (mSearchByPhoneNumberContacts.size() > 0) {
         Collections.sort(mSearchByPhoneNumberContacts, BeanContact.mAscComparator);
     }
     mSearchContacts.clear();
     mSearchContacts.addAll(mSearchByNameContacts);
     mSearchContacts.addAll(mSearchByPhoneNumberContacts);
     return mSearchContacts;
 }
      ```
5 . 通話記錄獲取
```java
public class CallLogHelper extends ContextWrapper {

 private SimpleDateFormat format;

 public List<BeanCallLog> getCalllogList(BaseFragment context) {
     HashMap<String, BeanCallLog> map = new HashMap<>();
     Numbercity nc = new Numbercity();
     List<BeanCallLog> list_bCallLogs = new ArrayList<BeanCallLog>();
     String[] projection = {CallLog.Calls.DATE, // 通話時(shí)間
             CallLog.Calls.NUMBER,// 電話號(hào)碼
             CallLog.Calls.TYPE, // 通話類型,主撥秧耗,被叫番官,未接
             CallLog.Calls.CACHED_NAME,// 顯示名稱
             CallLog.Calls.DURATION, // 通話時(shí)長
             CallLog.Calls._ID}; // 查詢的列
     if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
         context.requestPermissions(new String[]{Manifest.permission.READ_CALL_LOG}, CallFragment.READ_CALL_LOG_REQUEST_CODE);
         return list_bCallLogs;
     }
     Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null,
             null, CallLog.Calls.DEFAULT_SORT_ORDER);
     int id;
     String name;// 名稱
     String number;// 號(hào)碼
     String date_str;// 日期
     int type;// 來電:1,撥出:2,未接:3
     int duration; // 通話時(shí)長
     while (cursor.moveToNext()) {
         Date date = new Date(cursor.getLong(cursor
                 .getColumnIndex(CallLog.Calls.DATE)));
         number = cursor.getString(cursor
                 .getColumnIndex(CallLog.Calls.NUMBER));
         type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE));
         name = cursor.getString(cursor
                 .getColumnIndex(CallLog.Calls.CACHED_NAME));// 緩存的名稱與電話號(hào)碼庐完,如果它的存在
         id = cursor.getInt(cursor.getColumnIndex(CallLog.Calls._ID));
         duration = cursor.getInt(cursor
                 .getColumnIndex(CallLog.Calls.DURATION));
         date_str = format.format(date);
         BeanCallLog clb = new BeanCallLog();
         clb.setId(id);
         if (name == null) {
             name = "";
         }
         clb.setName(name);
         clb.setNumber(number);
         clb.setDate(date);
         clb.setType(type);
         clb.setDuration(duration);
         clb.setCount(1);
         clb.setPlace(nc.getCityByNum(number));
         if (!number.equals("-1")) {// 未知的號(hào)碼不加入通話記錄里面
             if (map.containsKey(clb.getName() + clb.getType() + date_str)) {
                 BeanCallLog beanCallLog = map.get(clb.getName() + clb.getType() + date_str);
                 int count = beanCallLog.getCount() + 1;
                 beanCallLog.setCount(count);
             } else {
                 map.put(clb.getName() + clb.getType() + date_str, clb);
             }
         }
     }
     cursor.close();
     nc.close();
     list_bCallLogs.addAll(map.values());
     Collections.sort(list_bCallLogs, BeanCallLog.mDescComparator);
     return list_bCallLogs;
 }

 public CallLogHelper(Context base) {
     super(base);
     format = new SimpleDateFormat("MM-dd");
 }
}

        ```
參考資料:
https://github.com/handsomezhou/PinyinSearchLibrary
Demo源碼:
https://github.com/luohaiah/ContactDemo
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市徘熔,隨后出現(xiàn)的幾起案子门躯,更是在濱河造成了極大的恐慌,老刑警劉巖酷师,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讶凉,死亡現(xiàn)場離奇詭異,居然都是意外死亡山孔,警方通過查閱死者的電腦和手機(jī)懂讯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來台颠,“玉大人域醇,你說我怎么就攤上這事∪叵保” “怎么了譬挚?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長酪呻。 經(jīng)常有香客問我减宣,道長,這世上最難降的妖魔是什么玩荠? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任漆腌,我火速辦了婚禮贼邓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闷尿。我一直安慰自己塑径,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布填具。 她就那樣靜靜地躺著统舀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劳景。 梳的紋絲不亂的頭發(fā)上誉简,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音盟广,去河邊找鬼闷串。 笑死,一個(gè)胖子當(dāng)著我的面吹牛筋量,可吹牛的內(nèi)容都是我干的烹吵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼桨武,長吁一口氣:“原來是場噩夢啊……” “哼肋拔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起玻募,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎一姿,沒想到半個(gè)月后七咧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叮叹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年艾栋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛉顽。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝗砾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出携冤,到底是詐尸還是另有隱情悼粮,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布曾棕,位于F島的核電站扣猫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏翘地。R本人自食惡果不足惜申尤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一癌幕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧昧穿,春花似錦勺远、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寥枝,卻和暖如春宪塔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背囊拜。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國打工某筐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冠跷。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓南誊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜜托。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抄囚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,738評(píng)論 0 33
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法橄务,類相關(guān)的語法幔托,內(nèi)部類的語法,繼承相關(guān)的語法蜂挪,異常的語法重挑,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,367評(píng)論 0 17
  • 啟動(dòng)通訊錄頁面獲取用戶點(diǎn)擊的 item 的數(shù)據(jù)(姓名棠涮、手機(jī)號(hào)) //啟動(dòng)通訊錄頁面 startActivityFo...
    ff_hh閱讀 2,220評(píng)論 0 0
  • 很久沒有打開筆記本谬哀,以至于剛打開時(shí)居然有點(diǎn)生疏感。像是在街角不經(jīng)意地遇見故人严肪,想寒暄幾句史煎,竟是如此不盡人意,匆促而...
    雨中葳蕤閱讀 589評(píng)論 2 5