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

经常看到一些Contact类的软件软件联系人列表在滚动时会在屏幕中间弹出一个提示信息,就是当前位置的联系人序号之类的,尝试实现了一下

 

先看效果:

 

 

 

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

 

布局文件 pop_overlay.xml

 

  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中

  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方法

 

  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 来实现的 可以下载来试下 还可以设置一些参数的

 

下面是调试代码:

 

  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. public class 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.                 } else if (((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.         return null;  
  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 static void main(String[] args) {  
  107.         String str = "测试";  
  108.         System.out.println(makeStringByStringSet(getPinyin(str)));  
  109.     }  
  110. }  

 

 

下面看弹出菜单的创建

 

  1. //监听条目单击事件  
  2.         listView.setOnItemClickListener(new OnItemClickListener(){  
  3.             @Override  
  4.             public void 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.                 return false;//如果返回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.                 return false;  
  41.             }  
  42.               
  43.         };  
  44.           
  45.         //监听长按事件 长按时弹出选择菜单   
  46.         listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){  
  47.             @Override  
  48.             public void 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

 

  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

 

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

  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等

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这个效果可以通过HTML、CSS、JavaScript实现。具体实现步骤如下: 1. 在HTML中创建导航菜单和子菜单的结构,使用无序列表(<ul>)和列表项(<li>)来实现。 2. 使用CSS设置导航菜单和子菜单的样式,包括位置、大小、颜色、字体等。 3. 使用JavaScript实现鼠标滑动事件,当鼠标滑动到导航菜单的某个菜单项上时,显示菜单项对应的子菜单,当鼠标离开导航菜单时,隐藏子菜单。 示例代码如下: HTML: ``` <nav> <ul> <li><a href="#">菜单1</a> <ul> <li><a href="#">子菜单1-1</a></li> <li><a href="#">子菜单1-2</a></li> <li><a href="#">子菜单1-3</a></li> </ul> </li> <li><a href="#">菜单2</a> <ul> <li><a href="#">子菜单2-1</a></li> <li><a href="#">子菜单2-2</a></li> <li><a href="#">子菜单2-3</a></li> </ul> </li> <li><a href="#">菜单3</a> <ul> <li><a href="#">子菜单3-1</a></li> <li><a href="#">子菜单3-2</a></li> <li><a href="#">子菜单3-3</a></li> </ul> </li> </ul> </nav> ``` CSS: ``` nav { background-color: #333; color: #fff; padding: 10px; } nav ul { list-style: none; margin: 0; padding: 0; display: inline-block; position: relative; } nav ul li { margin: 0; padding: 0; display: inline-block; } nav ul li a { display: block; color: #fff; text-decoration: none; padding: 10px; } nav ul ul { display: none; position: absolute; top: 100%; left: 0; background-color: #444; padding: 0; margin: 0; } nav ul ul li { display: block; margin: 0; padding: 0; } nav ul ul li a { display: block; color: #fff; text-decoration: none; padding: 10px; } nav ul li:hover > ul { display: block; } ``` JavaScript: ``` var menu = document.getElementsByTagName('nav')[0]; var menuItems = menu.getElementsByTagName('li'); for (var i = 0; i < menuItems.length; i++) { menuItems[i].addEventListener('mouseover', function() { this.getElementsByTagName('ul')[0].style.display = 'block'; }); menuItems[i].addEventListener('mouseout', function() { this.getElementsByTagName('ul')[0].style.display = 'none'; }); } ``` 在上述代码中,我们首先通过getElementsByTagName方法获取导航菜单,并获取所有菜单项,然后使用addEventListener方法为每个菜单项绑定鼠标滑动事件。当鼠标滑动菜单项上时,使用style.display属性将该菜单项对应的子菜单显示出来,当鼠标离开菜单项时,隐藏子菜单

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值