实现联系人列表滑动显示提示信息 以及弹出选择菜单

来源:互联网 发布:c语言基本数据类型用法 编辑:程序博客网 时间:2024/05/11 02:43
经常看到一些Contact类的软件软件联系人列表在滚动时会在屏幕中间弹出一个提示信息,就是当前位置的联系人序号之类的,尝试实现了一下

先看效果:

中间弹出的就是一个类似于Overlay的层

布局文件 pop_overlay.xml

view plain
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:textSize="70sp"   
  4.     android:textColor="#99ff00ff"   
  5.     android:background="#99fff34f"   
  6.     android:minWidth="80dip"   
  7.     android:maxWidth="80dip"   
  8.     android:padding="10dip"   
  9.     android:gravity="center"   
  10. />   

在onCreate方法中加载这个View并且通过addView加入到Activity中

view plain
  1. //滚动时弹出的提示框 
  2.         txtOverlay = (TextView) LayoutInflater.from(this).inflate(R.layout.pop_overlay,null);   
  3.        // 默认设置为不可见。  
  4.         txtOverlay.setVisibility(View.INVISIBLE);   
  5.         WindowManager.LayoutParams lp =new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT,   
  6.                 LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION,   
  7.                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,   
  8.                 PixelFormat.TRANSLUCENT);   
  9.         windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);   
  10.         windowManager.addView(txtOverlay, lp);   

然后可以通过实现 ListView.OnScrollListener接口来重写  onScroll 和 onScrollStateChanged方法

view plain
  1. boolean visible; 
  2.      
  3.     @Override 
  4.     public void onScroll(AbsListView view,int firstVisibleItem, 
  5.            int visibleItemCount,int totalItemCount) { 
  6.         Log.i("bb","onScroll"); 
  7.         Log.i("bb","visible:"+visible); 
  8.        int index = cursor.getColumnIndex("display_name"); 
  9.        if (visible) { 
  10.             cursor.moveToPosition(firstVisibleItem); 
  11.             String firstChar = Pinyin4j.getFirstChar(cursor.getString(index)); 
  12.             txtOverlay.setText(firstChar); 
  13.             txtOverlay.setVisibility(View.VISIBLE); 
  14.         } 
  15.     } 
  16.      
  17.     @Override 
  18.     public void onScrollStateChanged(AbsListView view,int scrollState) { 
  19.         visible =true
  20.         Log.i("bb","onScrollStateChanged"); 
  21.        //在onScrollStateChanged (AbsListView view, int scrollState) 中,scrollState有三种状态, 
  22.        //分别是开始滚动(SCROLL_STATE_FLING ),正在滚动(SCROLL_STATE_TOUCH_SCROLL ), 已经停止(SCROLL_STATE_IDLE ), 
  23.        if (scrollState == ListView.OnScrollListener.SCROLL_STATE_IDLE) { 
  24.             txtOverlay.setVisibility(View.INVISIBLE); 
  25.             visible =false
  26.         } 
  27.          
  28.     } 

这两个方法的调用时机是不同的,可以自己打印看一下

这里显示的是用户中文名的首字母  通过 pingyin4j.jar来实现的 可以下载来试下 还可以设置一些参数的

下面是调试代码:

view plain
  1. import java.util.HashSet; 
  2. import java.util.Set; 
  3. import net.sourceforge.pinyin4j.PinyinHelper; 
  4. import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; 
  5. import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; 
  6. import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; 
  7. import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType; 
  8. import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; 
  9. publicclass Pinyin4j { 
  10.     /**
  11.      * 字符串集合转换字符串(逗号分隔)
  12.      */ 
  13.     public static String makeStringByStringSet(Set<String> stringSet) { 
  14.         StringBuilder str =new StringBuilder(); 
  15.        int i = 0; 
  16.        for (String s : stringSet) { 
  17.            if (i == stringSet.size() - 1) { 
  18.                 str.append(s); 
  19.             }else
  20.                 str.append(s +","); 
  21.             } 
  22.             i++; 
  23.         } 
  24.        return str.toString().toLowerCase(); 
  25.     } 
  26.     /**
  27.      * 获取拼音集合
  28.      */ 
  29.     public static Set<String> getPinyin(String src) { 
  30.        if (src !=null && !src.trim().equalsIgnoreCase("")) { 
  31.            char[] srcChar; 
  32.             srcChar = src.toCharArray(); 
  33.            // 汉语拼音格式输出类 
  34.             HanyuPinyinOutputFormat hanYuPinOutputFormat =new HanyuPinyinOutputFormat(); 
  35.            // 输出设置,大小写,音标方式等 
  36.             hanYuPinOutputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); 
  37.             hanYuPinOutputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); 
  38.             hanYuPinOutputFormat.setVCharType(HanyuPinyinVCharType.WITH_V); 
  39.             String[][] temp =new String[src.length()][]; 
  40.            for (int i = 0; i < srcChar.length; i++) { 
  41.                char c = srcChar[i]; 
  42.                // 是中文或者a-z或者A-Z转换拼音(我的需求,是保留中文或者a-z或者A-Z) 
  43.                if (String.valueOf(c).matches("[//u4E00-//u9FA5]+")) { 
  44.                    try
  45.                         temp[i] = PinyinHelper.toHanyuPinyinStringArray( 
  46.                                 srcChar[i], hanYuPinOutputFormat); 
  47.                     }catch (BadHanyuPinyinOutputFormatCombination e) { 
  48.                         e.printStackTrace(); 
  49.                     } 
  50.                 }elseif (((int) c >= 65 && (int) c <= 90) 
  51.                         || ((int) c >= 97 && (int) c <= 122)) { 
  52.                     temp[i] =new String[] { String.valueOf(srcChar[i]) }; 
  53.                 }else
  54.                     temp[i] =new String[] {"" }; 
  55.                 } 
  56.             } 
  57.             String[] pingyinArray = Exchange(temp); 
  58.             Set<String> pinyinSet =new HashSet<String>(); 
  59.            for (int i = 0; i < pingyinArray.length; i++) { 
  60.                 pinyinSet.add(pingyinArray[i]); 
  61.             } 
  62.            return pinyinSet; 
  63.         } 
  64.        returnnull
  65.     } 
  66.     /**
  67.      * 递归
  68.      */ 
  69.     public static String[] Exchange(String[][] strJaggedArray) { 
  70.         String[][] temp = DoExchange(strJaggedArray); 
  71.        return temp[0]; 
  72.     } 
  73.     /**
  74.      * 递归
  75.      */ 
  76.     private static String[][] DoExchange(String[][] strJaggedArray) { 
  77.        int len = strJaggedArray.length; 
  78.        if (len >= 2) { 
  79.            int len1 = strJaggedArray[0].length; 
  80.            int len2 = strJaggedArray[1].length; 
  81.            int newlen = len1 * len2; 
  82.             String[] temp =new String[newlen]; 
  83.            int Index = 0; 
  84.            for (int i = 0; i < len1; i++) { 
  85.                for (int j = 0; j < len2; j++) { 
  86.                     temp[Index] = strJaggedArray[0][i] + strJaggedArray[1][j]; 
  87.                     Index++; 
  88.                 } 
  89.             } 
  90.             String[][] newArray =new String[len - 1][]; 
  91.            for (int i = 2; i < len; i++) { 
  92.                 newArray[i - 1] = strJaggedArray[i]; 
  93.             } 
  94.             newArray[0] = temp; 
  95.            return DoExchange(newArray); 
  96.         }else
  97.            return strJaggedArray; 
  98.         } 
  99.     } 
  100.     public static String getFirstChar(String str) { 
  101.        return makeStringByStringSet(getPinyin(str)).substring(0, 1); 
  102.     } 
  103.     /**
  104.      * @param args
  105.      */ 
  106.     public staticvoid main(String[] args) { 
  107.         String str ="测试"
  108.         System.out.println(makeStringByStringSet(getPinyin(str))); 
  109.     } 

下面看弹出菜单的创建

view plain
  1. //监听条目单击事件 
  2.         listView.setOnItemClickListener(new OnItemClickListener(){ 
  3.             @Override 
  4.            publicvoid onItemClick(AdapterView<?> parent, View view, 
  5.                    int position,long id) { 
  6.                 TextView tv = (TextView)view.findViewById(R.id.phonename); 
  7.                 Toast.makeText(ListViewDemo.this, tv.getText(), Toast.LENGTH_LONG).show(); 
  8.             } 
  9.              
  10.         }); 
  11.         listView.setOnItemLongClickListener(new OnItemLongClickListener(){ 
  12.             @Override 
  13.            public boolean onItemLongClick(AdapterView<?> parent, View view, 
  14.                    int position,long id) { 
  15.                 Toast.makeText(ListViewDemo.this,"长按一次", Toast.LENGTH_LONG).show(); 
  16.                returnfalse;//如果返回true 就不会调用下面onCreateContextMenu事件 
  17.             } 
  18.              
  19.         }); 
  20.          
  21.          
  22.        //长按弹出菜单选项的点击选择事件监听 
  23.         final OnMenuItemClickListener mOnMenuItemClickListener =new OnMenuItemClickListener(){ 
  24.             @Override 
  25.            public boolean onMenuItemClick(MenuItem item) { 
  26.                switch (item.getItemId()) { 
  27.                case 0: 
  28.                     Toast.makeText(ListViewDemo.this,"test1", Toast.LENGTH_LONG).show(); 
  29.                    break
  30.                case 1: 
  31.                     Toast.makeText(ListViewDemo.this,"test2", Toast.LENGTH_LONG).show(); 
  32.                    break
  33.                case 2: 
  34.                     Toast.makeText(ListViewDemo.this,"test3", Toast.LENGTH_LONG).show(); 
  35.                    break
  36.                case 3: 
  37.                     Toast.makeText(ListViewDemo.this,"test4", Toast.LENGTH_LONG).show(); 
  38.                    break
  39.                 } 
  40.                returnfalse
  41.             } 
  42.              
  43.         }; 
  44.          
  45.        //监听长按事件 长按时弹出选择菜单 
  46.         listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){ 
  47.             @Override 
  48.            publicvoid onCreateContextMenu(ContextMenu menu, View view,ContextMenuInfo arg2) { 
  49.                  
  50.                 menu.setHeaderTitle("提示框"); 
  51.                 menu.add(0, 0, 0,"test1").setOnMenuItemClickListener(mOnMenuItemClickListener); 
  52.                 menu.add(0, 1, 1,"test2").setOnMenuItemClickListener(mOnMenuItemClickListener); 
  53.                 menu.add(0, 2, 2,"test3").setOnMenuItemClickListener(mOnMenuItemClickListener); 
  54.                 menu.add(0, 3, 3,"test4").setOnMenuItemClickListener(mOnMenuItemClickListener); 
  55.             } 
  56.              
  57.         }); 

效果如上图,这里就有ListView种的几个点击事件


首先是单击事件 通过setOnItemClickListener 来监听


长按事件 通过 setOnItemLongClickListener 来监听 如果是长按就可以通过setOnCreateContextMenuListener这个事件来创建弹出菜单,注意如果要通过这种方式创建菜单需要在onItemLongClick方法中返回false

通过setOnCreateContextMenuListener事件来监听弹出菜单的点击事件

总之这里有N多的事件

还有一点看一下ListView的每个条目Item实现点击切换底色的效果

如图

点击是底色变成如果的颜色


这个可以在Item的布局文件中实现  来看布局文件 listviewdemoitem.xml

view plain
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:orientation="horizontal"   
  4.     android:layout_width="fill_parent"   
  5.     android:layout_height="fill_parent"   
  6.     android:background="#ffffff"       
  7.     >     
  8.     <RelativeLayout   
  9.         android:layout_width="wrap_content"   
  10.         android:layout_height="fill_parent"   
  11.         android:background="@drawable/listview_selected"   
  12.         android:padding="6px"   
  13.     >   
  14.     <TextView   
  15.         android:id="@+id/phonename"     
  16.         android:layout_width="fill_parent"    
  17.         android:layout_height="wrap_content"    
  18.         android:textSize="20px"   
  19.         android:textColor="#000000"   
  20.         />   
  21.     <TextView   
  22.         android:layout_below="@id/phonename" 
  23.         android:id="@+id/phonenumber"     
  24.         android:layout_width="fill_parent"    
  25.         android:layout_height="wrap_content"    
  26.         android:textSize="16px"   
  27.         android:textColor="#000000"   
  28.         />   
  29.         <ImageView   
  30.             android:layout_alignParentRight="true" 
  31.             android:layout_width="wrap_content"    
  32.             android:layout_height="wrap_content"  
  33.             android:src="@drawable/menu_city_manager" 
  34.             android:layout_gravity="right" 
  35.             /> 
  36.      </RelativeLayout>   
  37. </LinearLayout>   

外面是一个LinerLayout 作为底色 防止滚动的时候底色变成黑色

里面用一个RelativeLayout实现了布局调整,它的android:background="@drawable/listview_selected"  属性通过一个Selector

来实现焦点 点击等操作时的背景切换

view plain
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">   
  3.     <item android:state_pressed="true" android:drawable="@drawable/list_selector_background_pressed" />   
  4. </selector>   

这里简单实现了一下,还可以有其他的设置 譬如 android:state_focus等

原创粉丝点击