在这次代码编写当中,我主要用到了WindowManager来显示友好提示
在对数组进行排序的时候,我们可以用 Arrays.sort()方法轻松实现按字母顺序排序。
另外在实现点击字母后让ListView滚动到以该字母开头的相应位置效果时,我们要用到如下方法:
一个是通过public static int binarySearch(Object[] a,Object key) 方法来获得该字母出现的Item在ListView中的位置position,
另一个就是 list.setSelection(localPosition); 来让List指向对应位置的Item。
当你对这些方法都有所了解了以后,下面我们开始设计我们的Demo。
我们先建立一个名为ContactsDemo的工程,然后就是代码部分了:
第一步,在res/layout的main.xml中我们来设置Activity中显示ListView上下层显示的效果,其实就是一个相对布局。
第二步,我们在layout中建一个list_popup_char_hint.xml,这是用来通过WindowManager显示友好提示的。
第三步,是list_item.xml用来设置ListView中Items的布局。
第四步,是一个textview.xml用来显示右边覆盖在ListView上的ListView的Items
第五步,我们建一个名为ContactsDemo的类,然后就是实现功能的代码了,里面有非常详尽的注释,大家慢慢看吧。
package com.ContactsDemo; import java.util.ArrayList; import java.util.Arrays; import android.app.Activity; import android.content.Context; import android.graphics.PixelFormat; import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView.OnItemClickListener; /** * @author Mr.罗 * */ public class ContactsDemo extends Activity implements OnItemClickListener,OnScrollListener{ /** Called when the activity is first created. */ private MyListAdapter adapter; private ArrayListwebNameArr; private WindowManager windowManager; private TextView txtOverlay; //用来放在WindowManager中显示提示字符 private Handler handler; private DisapearThread disapearThread; private int scrollState; //滚动的状态 private ListView list,listview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtOverlay = (TextView) LayoutInflater.from(this).inflate(R.layout.list_popup_char_hint, null); // 默认设置为不可见。 txtOverlay.setVisibility(View.INVISIBLE); //设置WindowManager WindowManager.LayoutParams lp = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION, //设置为无焦点状态 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, //半透明效果 PixelFormat.TRANSLUCENT); windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); windowManager.addView(txtOverlay, lp); handler = new Handler(); disapearThread = new DisapearThread(); Arrays.sort(stringArr,String.CASE_INSENSITIVE_ORDER); //大小写不敏感 webNameArr = new ArrayList (); for (int i = 0; i < stringArr.length; i++) { webNameArr.add(stringArr[i]); } list = (ListView)this.findViewById(R.id.list); //联系人ListView listview = (ListView)this.findViewById(R.id.listview); //拼音查询ListView adapter = new MyListAdapter(this); list.setAdapter(adapter);//将数据适配器与Activity进行绑定 list.setOnScrollListener(this); ArrayAdapter adapter1 = new ArrayAdapter (this,R.layout.textview,py); listview.setAdapter(adapter1); listview.setDivider(null); listview.setOnItemClickListener(this); } private class DisapearThread implements Runnable { public void run() { // 避免在1.5s内,用户再次拖动时提示框又执行隐藏命令。 if (scrollState == ListView.OnScrollListener.SCROLL_STATE_IDLE) { txtOverlay.setVisibility(View.INVISIBLE); } } } //继承BaseAdapter来设置ListView每行的内容 public final class ViewHolder { public TextView firstCharHintTextView; public TextView orderTextView; public TextView nameTextView; public TextView urlTextView; public ImageView imgView; } private class MyListAdapter extends BaseAdapter { private LayoutInflater inflater; public MyListAdapter(Context context) { this.inflater = LayoutInflater.from(context); } public int getCount() { return webNameArr.size(); } public Object getItem(int position) { return webNameArr.get(position); } public long getItemId(int position) { return position; } public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = inflater.inflate(R.layout.list_item, null); holder = new ViewHolder(); holder.firstCharHintTextView = (TextView) convertView.findViewById(R.id.text_first_char_hint); holder.orderTextView = (TextView) convertView.findViewById(R.id.order); holder.nameTextView = (TextView) convertView.findViewById(R.id.content); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.orderTextView.setText(String.valueOf(position + 1) + "."); holder.nameTextView.setText(webNameArr.get(position)); int idx = position - 1; //判断前后Item是否匹配,如果不匹配则设置并显示,匹配则取消 char previewChar = idx >= 0 ? stringArr[idx].charAt(0) : ' '; char currentChar = stringArr[position].charAt(0); //将小写字符转换为大写字符 char newPreviewChar = Character.toUpperCase(previewChar); char newCurrentChar = Character.toUpperCase(currentChar); if (newCurrentChar != newPreviewChar) { holder.firstCharHintTextView.setVisibility(View.VISIBLE); holder.firstCharHintTextView.setText(String.valueOf(newCurrentChar)); } else { // 此段代码不可缺:实例化一个CurrentView后,会被多次赋值并且只有最后一次赋值的position是正确 holder.firstCharHintTextView.setVisibility(View.GONE); } return convertView; } } public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // 以中间的ListItem为标准项来显示。 txtOverlay.setText(String.valueOf(stringArr[firstVisibleItem + (visibleItemCount >> 1)].charAt(0)).toUpperCase()); } public void onScrollStateChanged(AbsListView view, int scrollState) { this.scrollState = scrollState; if (scrollState == ListView.OnScrollListener.SCROLL_STATE_IDLE) { handler.removeCallbacks(disapearThread); // 提示延迟1.5s再消失 handler.postDelayed(disapearThread, 1500); } else { txtOverlay.setVisibility(View.VISIBLE); } } public void onItemClick(AdapterView> parent, View view, int position, long id) { String s = ((TextView)view).getText().toString(); txtOverlay.setText(s); txtOverlay.setVisibility(View.VISIBLE); handler.removeCallbacks(disapearThread); // 提示延迟1.5s再消失 handler.postDelayed(disapearThread, 1500); int localPosition = binSearch(stringArr,s); //接收返回值 if(localPosition!=-1){ txtOverlay.setVisibility(View.INVISIBLE); //防止点击出现的txtOverlay与滚动出现的txtOverlay冲突 list.setSelection(localPosition); //让List指向对应位置的Item } } //将选中的py与stringArr的首字符进行匹配并返回对应字符串在数组中的位置 public static int binSearch(String[] string , String s ){ for(int i=0;i