編輯:Android開發實例
經常看到一些Contact類的軟件軟件聯系人列表在滾動時會在屏幕中間彈出一個提示信息,就是當前位置的聯系人序號之類的,嘗試實現了一下
先看效果:
中間彈出的就是一個類似於Overlay的層
布局文件 pop_overlay.xml
- <?xml version="1.0" encoding="utf-8"?>
- <TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:textSize="70sp"
- android:textColor="#99ff00ff"
- android:background="#99fff34f"
- android:minWidth="80dip"
- android:maxWidth="80dip"
- android:padding="10dip"
- android:gravity="center"
- />
在onCreate方法中加載這個View並且通過addView加入到Activity中
- //滾動時彈出的提示框
- txtOverlay = (TextView) LayoutInflater.from(this).inflate(R.layout.pop_overlay, null);
- // 默認設置為不可見。
- txtOverlay.setVisibility(View.INVISIBLE);
- 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);
然後可以通過實現 ListView.OnScrollListener接口來重寫 onScroll 和 onScrollStateChanged方法
- boolean visible;
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- Log.i("bb", "onScroll");
- Log.i("bb", "visible:"+visible);
- int index = cursor.getColumnIndex("display_name");
- if (visible) {
- cursor.moveToPosition(firstVisibleItem);
- String firstChar = Pinyin4j.getFirstChar(cursor.getString(index));
- txtOverlay.setText(firstChar);
- txtOverlay.setVisibility(View.VISIBLE);
- }
- }
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- visible = true;
- Log.i("bb", "onScrollStateChanged");
- //在onScrollStateChanged (AbsListView view, int scrollState) 中,scrollState有三種狀態,
- //分別是開始滾動(SCROLL_STATE_FLING ),正在滾動(SCROLL_STATE_TOUCH_SCROLL ), 已經停止(SCROLL_STATE_IDLE ),
- if (scrollState == ListView.OnScrollListener.SCROLL_STATE_IDLE) {
- txtOverlay.setVisibility(View.INVISIBLE);
- visible = false;
- }
- }
這兩個方法的調用時機是不同的,可以自己打印看一下
這裡顯示的是用戶中文名的首字母 通過 pingyin4j.jar 來實現的 可以下載來試下 還可以設置一些參數的
下面是調試代碼:
- import java.util.HashSet;
- import java.util.Set;
- import net.sourceforge.pinyin4j.PinyinHelper;
- import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
- import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
- import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
- import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
- import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
- public class Pinyin4j {
- /**
- * 字符串集合轉換字符串(逗號分隔)
- */
- public static String makeStringByStringSet(Set<String> stringSet) {
- StringBuilder str = new StringBuilder();
- int i = 0;
- for (String s : stringSet) {
- if (i == stringSet.size() - 1) {
- str.append(s);
- } else {
- str.append(s + ",");
- }
- i++;
- }
- return str.toString().toLowerCase();
- }
- /**
- * 獲取拼音集合
- */
- public static Set<String> getPinyin(String src) {
- if (src != null && !src.trim().equalsIgnoreCase("")) {
- char[] srcChar;
- srcChar = src.toCharArray();
- // 漢語拼音格式輸出類
- HanyuPinyinOutputFormat hanYuPinOutputFormat = new HanyuPinyinOutputFormat();
- // 輸出設置,大小寫,音標方式等
- hanYuPinOutputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
- hanYuPinOutputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
- hanYuPinOutputFormat.setVCharType(HanyuPinyinVCharType.WITH_V);
- String[][] temp = new String[src.length()][];
- for (int i = 0; i < srcChar.length; i++) {
- char c = srcChar[i];
- // 是中文或者a-z或者A-Z轉換拼音(我的需求,是保留中文或者a-z或者A-Z)
- if (String.valueOf(c).matches("[//u4E00-//u9FA5]+")) {
- try {
- temp[i] = PinyinHelper.toHanyuPinyinStringArray(
- srcChar[i], hanYuPinOutputFormat);
- } catch (BadHanyuPinyinOutputFormatCombination e) {
- e.printStackTrace();
- }
- } else if (((int) c >= 65 && (int) c <= 90)
- || ((int) c >= 97 && (int) c <= 122)) {
- temp[i] = new String[] { String.valueOf(srcChar[i]) };
- } else {
- temp[i] = new String[] { "" };
- }
- }
- String[] pingyinArray = Exchange(temp);
- Set<String> pinyinSet = new HashSet<String>();
- for (int i = 0; i < pingyinArray.length; i++) {
- pinyinSet.add(pingyinArray[i]);
- }
- return pinyinSet;
- }
- return null;
- }
- /**
- * 遞歸
- */
- public static String[] Exchange(String[][] strJaggedArray) {
- String[][] temp = DoExchange(strJaggedArray);
- return temp[0];
- }
- /**
- * 遞歸
- */
- private static String[][] DoExchange(String[][] strJaggedArray) {
- int len = strJaggedArray.length;
- if (len >= 2) {
- int len1 = strJaggedArray[0].length;
- int len2 = strJaggedArray[1].length;
- int newlen = len1 * len2;
- String[] temp = new String[newlen];
- int Index = 0;
- for (int i = 0; i < len1; i++) {
- for (int j = 0; j < len2; j++) {
- temp[Index] = strJaggedArray[0][i] + strJaggedArray[1][j];
- Index++;
- }
- }
- String[][] newArray = new String[len - 1][];
- for (int i = 2; i < len; i++) {
- newArray[i - 1] = strJaggedArray[i];
- }
- newArray[0] = temp;
- return DoExchange(newArray);
- } else {
- return strJaggedArray;
- }
- }
- public static String getFirstChar(String str) {
- return makeStringByStringSet(getPinyin(str)).substring(0, 1);
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- String str = "測試";
- System.out.println(makeStringByStringSet(getPinyin(str)));
- }
- }
下面看彈出菜單的創建
- //監聽條目單擊事件
- listView.setOnItemClickListener(new OnItemClickListener(){
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- TextView tv = (TextView)view.findViewById(R.id.phonename);
- Toast.makeText(ListViewDemo.this, tv.getText(), Toast.LENGTH_LONG).show();
- }
- });
- listView.setOnItemLongClickListener(new OnItemLongClickListener(){
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view,
- int position, long id) {
- Toast.makeText(ListViewDemo.this, "長按一次", Toast.LENGTH_LONG).show();
- return false;//如果返回true 就不會調用下面onCreateContextMenu事件
- }
- });
- //長按彈出菜單選項的點擊選擇事件監聽
- final OnMenuItemClickListener mOnMenuItemClickListener = new OnMenuItemClickListener(){
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case 0:
- Toast.makeText(ListViewDemo.this, "test1", Toast.LENGTH_LONG).show();
- break;
- case 1:
- Toast.makeText(ListViewDemo.this, "test2", Toast.LENGTH_LONG).show();
- break;
- case 2:
- Toast.makeText(ListViewDemo.this, "test3", Toast.LENGTH_LONG).show();
- break;
- case 3:
- Toast.makeText(ListViewDemo.this, "test4", Toast.LENGTH_LONG).show();
- break;
- }
- return false;
- }
- };
- //監聽長按事件 長按時彈出選擇菜單
- listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){
- @Override
- public void onCreateContextMenu(ContextMenu menu, View view,ContextMenuInfo arg2) {
- menu.setHeaderTitle("提示框");
- menu.add(0, 0, 0, "test1").setOnMenuItemClickListener(mOnMenuItemClickListener);
- menu.add(0, 1, 1, "test2").setOnMenuItemClickListener(mOnMenuItemClickListener);
- menu.add(0, 2, 2, "test3").setOnMenuItemClickListener(mOnMenuItemClickListener);
- menu.add(0, 3, 3, "test4").setOnMenuItemClickListener(mOnMenuItemClickListener);
- }
- });
效果如上圖,這裡就有ListView種的幾個點擊事件
首先是單擊事件 通過setOnItemClickListener 來監聽
長按事件 通過 setOnItemLongClickListener 來監聽 如果是長按就可以通過setOnCreateContextMenuListener這個事件來創建彈出菜單,注意如果要通過這種方式創建菜單需要在onItemLongClick方法中返回false
通過setOnCreateContextMenuListener事件來監聽彈出菜單的點擊事件
總之這裡有N多的事件
還有一點看一下ListView的每個條目Item實現點擊切換底色的效果
如圖
點擊是底色變成如果的顏色
這個可以在Item的布局文件中實現 來看布局文件 listviewdemoitem.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#ffffff"
- >
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:background="@drawable/listview_selected"
- android:padding="6px"
- >
- <TextView
- android:id="@+id/phonename"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="20px"
- android:textColor="#000000"
- />
- <TextView
- android:layout_below="@id/phonename"
- android:id="@+id/phonenumber"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="16px"
- android:textColor="#000000"
- />
- <ImageView
- android:layout_alignParentRight="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/menu_city_manager"
- android:layout_gravity="right"
- />
- </RelativeLayout>
- </LinearLayout>
外面是一個LinerLayout 作為底色 防止滾動的時候底色變成黑色
裡面用一個RelativeLayout實現了布局調整,它的android:background="@drawable/listview_selected" 屬性通過一個Selector
來實現焦點 點擊等操作時的背景切換
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/list_selector_background_pressed" />
- </selector>
這裡簡單實現了一下,還可以有其他的設置 譬如 android:state_focus等
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
先明確幾個概念的區別: padding margin都是邊距的含義,關鍵問題得明白是什麼相對什麼的邊距. padding是控件的內容相對控件的邊緣的邊距. mar
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
首先看程序界面如下! 1、布局文件:代碼如下:<AbsoluteLayout xmlns:android=http://schemas.android.c