几乎在每个手机上的联系人列表都可以看到右边有个字母列表视图,这里可以通过自定义View实现,在界面右边部分绘制A~Z这些字母,并提供触摸监听器,这里结合上一篇文章将字母列表视图运用在其中,里面用得MyListAdapter、MyViewPager、PinYinUtil都和前面两篇文章一样。代码如下:
MainActivity:
package com.home; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import com.home.AlphabetScrollBar.OnTouchBarListener; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnTouchBarListener { private ListView listView; private List<String> list = new ArrayList<String>();// 数据集合 private AlphabetScrollBar asb;// 字母列视图View private TextView noticeView;// 提示选中的组件 private EditText searchText;// 搜索框 private MyListAdapter adapter;// 适配器 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getContacts(); setContentView(R.layout.activity_main); asb = (AlphabetScrollBar) findViewById(R.id.main_asb); asb.setOnTouchBarListener(this); noticeView = (TextView) findViewById(R.id.main_notice_tv); asb.setTextView(noticeView); // 根据拼音对联系人进行排序 Collections.sort(list, new ComparatorPY()); listView = (ListView) findViewById(R.id.main_lv); adapter = new MyListAdapter(this, list); listView.setAdapter(adapter); searchText = (EditText) findViewById(R.id.main_et); searchText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { if (!"".equals(cs.toString().trim())) { filter(cs.toString().trim());// 根据编辑框值过滤联系人并更新联系人列表 asb.setVisibility(View.GONE); } else { asb.setVisibility(View.VISIBLE); adapter.updateListView(list); } } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) { } }); } @Override public void onTouch(String letter) { // 触摸字母列时,将联系人列表更新到首字母出现的位置 for (int i = 0; i < list.size(); i++) { if (PinYinUtil.getFirstLetter(list.get(i), true).compareToIgnoreCase(letter) == 0) { listView.setSelection(i); break; } } } public class ComparatorPY implements Comparator<String> { @Override public int compare(String name1, String name2) { String pinyin1 = PinYinUtil.getPinYin(name1); String pinyin2 = PinYinUtil.getPinYin(name2); return pinyin1.compareToIgnoreCase(pinyin2); } } /** * 获取系统联系人姓名(为测试方便这里只获取姓名) */ public void getContacts() { ContentResolver resolver = getContentResolver(); Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); list.add(name); } if (cursor != null) { cursor.close(); } } /** * 过滤联系人并刷新列表 * * @param filterStr */ private void filter(String filterStr) { ArrayList<String> filterList = new ArrayList<String>(); for (int i = 0; i < list.size(); i++) { // 按拼音首字母进行匹配过滤 if (isContained(PinYinUtil.getFirstSpell(list.get(i)), filterStr)) { filterList.add(list.get(i)); } } // 如果没有匹配的联系人 if (filterList.size() == 0) { Toast.makeText(this, "没有匹配的联系人", Toast.LENGTH_SHORT).show(); } adapter.updateListView(filterList); // 更新联系人列表 } /** * 判断bigStr是否包含smallStr * * @param bigStr * @param smallStr * @return */ public boolean isContained(String bigStr, String smallStr) { if (bigStr.toUpperCase().indexOf(smallStr.toUpperCase()) > -1) { return true; } else { return false; } } }
AlphabetScrollBar:
package com.home; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; public class AlphabetScrollBar extends View { private Paint paint = new Paint(); private String[] alphabet = new String[] { "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 boolean pressed;// 是否按下 private int curIndex = -1; private int oldIndex = -1; private OnTouchBarListener touchListener; private TextView noticeView; public AlphabetScrollBar(Context context, AttributeSet attrs, int arg2) { super(context, attrs, arg2); } public AlphabetScrollBar(Context context, AttributeSet attrs) { super(context, attrs); } public AlphabetScrollBar(Context context) { super(context); } public void setTextView(TextView noticeView) { this.noticeView = noticeView; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = this.getWidth(); int height = this.getHeight(); // 每个字母的高度 int singleLetterH = height / alphabet.length; if (pressed) { // 如果处于按下状态,改变背景及相应字体的颜色 canvas.drawColor(Color.parseColor("#40000000")); } for (int i = 0; i < alphabet.length; i++) { paint.setColor(Color.parseColor("#000000")); paint.setAntiAlias(true); paint.setTextSize(23); float x = width / 2 - paint.measureText(alphabet[i]) / 2; float y = singleLetterH * i + singleLetterH; if (i == curIndex) { paint.setColor(Color.parseColor("#0000FF")); paint.setFakeBoldText(true); } canvas.drawText(alphabet[i], x, y, paint); paint.reset(); } } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: pressed = true; handleTouchEvent(event); return true; case MotionEvent.ACTION_UP: if (noticeView != null) { noticeView.setVisibility(View.INVISIBLE); } pressed = false; curIndex = -1; this.invalidate(); return true; case MotionEvent.ACTION_MOVE: handleTouchEvent(event); return true; default: return super.onTouchEvent(event); } } /** * 监听器回调接口 */ public static interface OnTouchBarListener { void onTouch(String letter); } /** * 设置监听的方法,供外部调用 */ public void setOnTouchBarListener(OnTouchBarListener listener) { touchListener = listener; } /** * 处理触摸事件 * * @param event */ private void handleTouchEvent(MotionEvent event) { curIndex = (int) (event.getY() / this.getHeight() * alphabet.length); if (touchListener != null && curIndex != oldIndex) { if ((curIndex >= 0) && (curIndex < alphabet.length)) { touchListener.onTouch(alphabet[curIndex]); this.invalidate(); } oldIndex = curIndex; } if (curIndex >= 0 && curIndex < alphabet.length) { noticeView.setText(alphabet[curIndex]); noticeView.setVisibility(View.VISIBLE); } } }
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/main_et" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="搜索联系人" android:textSize="15dp" /> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/main_lv" android:layout_width="match_parent" android:layout_height="match_parent" android:dividerHeight="1dp" /> <TextView android:id="@+id/main_notice_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:textSize="50sp" android:visibility="gone" /> <com.home.AlphabetScrollBar android:id="@+id/main_asb" android:layout_width="30dp" android:layout_height="match_parent" android:layout_gravity="right" /> </FrameLayout> </LinearLayout>
在activity属性里面加入下面一句,可以禁止一运行就启动输入法:
android:windowSoftInputMode="stateHidden|adjustPan"
原文:http://blog.csdn.net/u010142437/article/details/22314585