歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android模仿QQ的左右滑動切換界面和下拉更新的效果

因為功能還沒有完全實現,所以效果不是太好,不過呢,還是能實現,左右滑動時候切換界面和顯示QQ好友列表的簡單功能!!好了,廢話不多說了看看實現的過程吧!

1.首先看看布局

主布局main.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <HorizontalScrollView  
  8.         android:id="@+id/horizontalscrollview"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:background="@drawable/item"  
  12.         android:fadingEdge="@null"  
  13.         android:scrollbars="none" >  
  14.   
  15.         <LinearLayout  
  16.             android:id="@+id/linearlayout"  
  17.             android:layout_width="match_parent"  
  18.             android:layout_height="match_parent"  
  19.             android:orientation="horizontal"  
  20.             >  
  21.         </LinearLayout>  
  22.     </HorizontalScrollView>  
  23.   
  24.     <android.support.v4.view.ViewPager  
  25.         android:id="@+id/viewpaper"  
  26.         android:layout_width="fill_parent"  
  27.         android:layout_height="match_parent"  
  28.         android:layout_weight="1" >  
  29.     </android.support.v4.view.ViewPager>  
  30.   
  31. </LinearLayout>  

2,接著看看QQonline.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical"   
  6.     android:background="@drawable/image2">  
  7.   
  8.       
  9. <ExpandableListView   
  10.     android:id="@+id/elistview"  
  11.     android:layout_width="fill_parent"   
  12.     android:layout_height="wrap_content"   
  13.     android:layout_marginLeft="5dp"  
  14.      
  15.       
  16.     />  
  17.   
  18. </LinearLayout>  

3.接著看看下拉更新的布局pullrefresh.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="@drawable/image1"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <com.wang.pullrefresh.MyListView  
  9.         android:id="@+id/listView"  
  10.         android:layout_width="fill_parent"  
  11.         android:layout_height="fill_parent" />  
  12.   
  13.   
  14. </LinearLayout>  
4.下拉更新過程實現的布局refresh.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content" >  
  5.   
  6.     <RelativeLayout  
  7.         android:id="@+id/head_contentLayout"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:paddingLeft="30dp" >  
  11.   
  12.         <FrameLayout  
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"  
  15.             android:layout_alignParentLeft="true"  
  16.             android:layout_centerVertical="true" >  
  17.   
  18.             <ImageView  
  19.                 android:id="@+id/head_arrowImageView"  
  20.                 android:layout_width="wrap_content"  
  21.                 android:layout_height="wrap_content"  
  22.                 android:layout_gravity="center"  
  23.                 android:src="@drawable/down" />  
  24.   
  25.             <ProgressBar  
  26.                 android:id="@+id/head_progressBar"  
  27.                 style="?android:attr/progressBarStyleSmall"  
  28.                 android:layout_width="wrap_content"  
  29.                 android:layout_height="wrap_content"  
  30.                 android:layout_gravity="center"  
  31.                 android:visibility="gone" />  
  32.         </FrameLayout>  
  33.   
  34.         <LinearLayout  
  35.             android:layout_width="wrap_content"  
  36.             android:layout_height="wrap_content"  
  37.             android:layout_centerHorizontal="true"  
  38.             android:gravity="center_horizontal"  
  39.             android:orientation="vertical" >  
  40.   
  41.             <TextView  
  42.                 android:id="@+id/head_tipsTextView"  
  43.                 android:layout_width="wrap_content"  
  44.                 android:layout_height="wrap_content"  
  45.                 android:text="下拉可以刷新"  
  46.                 android:textSize="15dp" />  
  47.   
  48.             <TextView  
  49.                 android:id="@+id/head_lastUpdatedTextView"  
  50.                 android:layout_width="wrap_content"  
  51.                 android:layout_height="wrap_content"  
  52.                 android:text="上次更新時間:"  
  53.                 android:textSize="12dp" />  
  54.         </LinearLayout>  
  55.     </RelativeLayout>  
  56.   
  57. </LinearLayout>  
5.下拉更新的列表顯示的布局list_item.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:gravity="center_vertical"  
  6.     android:orientation="horizontal" >  
  7.   
  8.     <ImageView  
  9.         android:id="@+id/imageView_item"  
  10.         android:layout_width="60dp"  
  11.         android:layout_height="60dp"  
  12.         android:layout_marginLeft="5dp"  
  13.         android:src="@drawable/qq" />  
  14.   
  15.     <TextView  
  16.         android:id="@+id/textView_item"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_height="wrap_content"  
  19.         android:layout_marginLeft="10dp"  
  20.         android:textColor="#FFFFFF"  
  21.         />  
  22.   
  23. </LinearLayout>  
6.接著看看還沒有完善的QQ聊天信息的布局main3.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical"   
  6.     android:background="@drawable/image3">  
  7.   
  8.        
  9.   
  10. </LinearLayout>  

7.接著看看主活動的實現過程ViewPaper1Activity.java

  1. package com.wang;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.app.ActivityGroup;  
  6. import android.content.Intent;  
  7. import android.graphics.Bitmap;  
  8. import android.graphics.BitmapFactory;  
  9. import android.graphics.drawable.BitmapDrawable;  
  10. import android.os.Bundle;  
  11. import android.support.v4.view.PagerAdapter;  
  12. import android.support.v4.view.ViewPager;  
  13. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  14. import android.view.Gravity;  
  15. import android.view.View;  
  16. import android.view.Window;  
  17. import android.view.WindowManager;  
  18. import android.view.View.OnClickListener;  
  19. import android.widget.HorizontalScrollView;  
  20. import android.widget.LinearLayout;  
  21. import android.widget.RadioButton;  
  22. import android.widget.RadioGroup;  
  23. import android.widget.TextView;  
  24. import android.widget.LinearLayout.LayoutParams;  
  25.   
  26. public class ViewPaper1Activity extends ActivityGroup implements  
  27.         OnClickListener {  
  28.     private RadioGroup radioGroup;  
  29.   
  30.     private String array[] = { "QQ空間""QQ""QQ消息" };  
  31.     private LinearLayout linearLayout;  
  32.     private ArrayList<TextView> textViews;  
  33.     private ViewPager viewPager;  
  34.     private ArrayList<View> pageViews;  
  35.     private HorizontalScrollView horizontalScrollView;  
  36.   
  37.     /*** 
  38.      *初始化視圖 
  39.      *  
  40.      *  
  41.      */  
  42.     void InItView() {  
  43.         // 構造一個新的ArrayList實例對象   
  44.         pageViews = new ArrayList<View>();  
  45.         /** 
  46.          *   開始一個新的活動中運行的組織。 每一個活動你開始必須有一個獨一無二的字符串標識與其相關聯 
  47.          * **/  
  48.         View view1 = getLocalActivityManager().startActivity("main1",  
  49.                 new Intent(this, pullrefreshtest.class)).getDecorView();  
  50.         View view2 = getLocalActivityManager().startActivity("main2",  
  51.                 new Intent(this, QQonline.class)).getDecorView();  
  52.         View view3 = getLocalActivityManager().startActivity("main3",  
  53.                 new Intent(this, main3.class)).getDecorView();  
  54.         // 添加指定的對象在文章末尾的ArrayList。   
  55.         pageViews.add(view1);  
  56.         pageViews.add(view2);  
  57.         pageViews.add(view3);  
  58.     }  
  59.   
  60.     /*** 
  61.      * 初始化話標題欄 
  62.      */  
  63.     void InItTitle() {  
  64.         // 獲取窗口管理器顯示自定義窗口,去掉默認顯示對象。得到1/3屏幕寬度   
  65.         int width = getWindowManager().getDefaultDisplay().getWidth() / 3;  
  66.   
  67.         for (int i = 0; i < array.length; i++) {  
  68.             // 聲明一個radioButton對象   
  69.             RadioButton radioButton = new RadioButton(thisnull);  
  70.             radioButton.setText(array[i]);  
  71.             radioButton.setWidth(width);  
  72.             radioButton.setHeight(70);  
  73.             // 集水平對齊文本和垂直重力的時候將會使用有額外的空間在TextView超出要求的文本本身   
  74.             radioButton.setGravity(Gravity.CENTER);  
  75.             // 添加子視圖。如果沒有布局參數對孩子已經設置,默認參數對於這個ViewGroup上設置的孩子。   
  76.             radioGroup.addView(radioButton);  
  77.         }  
  78.     }  
  79.   
  80.     /*** 
  81.      * 初始化文本 
  82.      */  
  83.     void initTextView() {  
  84.         // 聲明一個ArrayList對象   
  85.         textViews = new ArrayList<TextView>();  
  86.         // 獲取窗口管理器顯示自定義窗口,去掉默認顯示對象。得到1/3屏幕寬度   
  87.         int width = getWindowManager().getDefaultDisplay().getWidth() / 3;  
  88.         int height = 60;  
  89.         for (int i = 0; i < array.length; i++) {  
  90.             TextView textView = new TextView(this);  
  91.             textView.setText(array[i]);  
  92.             textView.setTextSize(17);  
  93.             textView.setWidth(width);  
  94.             textView.setHeight(height - 30);  
  95.             textView.setGravity(Gravity.CENTER);  
  96.             textView.setId(i);  
  97.             // 設置文本的監聽事件   
  98.             textView.setOnClickListener(this);  
  99.             textViews.add(textView);  
  100.             LinearLayout.LayoutParams layoutParams = new LayoutParams(  
  101.                     LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  102.             layoutParams.width = 1;  
  103.             layoutParams.height = height - 40;  
  104.             layoutParams.gravity = Gravity.CENTER;  
  105.             // 添加子視圖。如果沒有布局參數對孩子已經設置,默認參數對於這個ViewGroup上設置的孩子。   
  106.             linearLayout.addView(textView);  
  107.   
  108.         }  
  109.     }  
  110.   
  111.     /*** 
  112.      * 選中後的處理 
  113.      */  
  114.     public void select(int id) {  
  115.         for (int i = 0; i < array.length; i++) {  
  116.             if (id == i) {  
  117.                 // 得到圖片的資源   
  118.                 Bitmap bitmap = BitmapFactory.decodeResource(getResources(),  
  119.                         R.drawable.itembg);  
  120.                 // 設置背景圖   
  121.                 textViews.get(id).setBackgroundDrawable(  
  122.                         new BitmapDrawable(bitmap));  
  123.                 viewPager.setCurrentItem(i);  
  124.             }  
  125.   
  126.             else {  
  127.                 textViews.get(i).setBackgroundDrawable(new BitmapDrawable());  
  128.             }  
  129.         }  
  130.     }  
  131.   
  132.     @Override  
  133.     public void onCreate(Bundle savedInstanceState) {  
  134.         super.onCreate(savedInstanceState);  
  135.         // 去除標題欄   
  136.         this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
  137.         // 取消狀態欄,充滿全屏   
  138.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  139.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  140.   
  141.         setContentView(R.layout.main);  
  142.         // 實例化組件   
  143.         linearLayout = (LinearLayout) findViewById(R.id.linearlayout);  
  144.         viewPager = (ViewPager) findViewById(R.id.viewpaper);  
  145.         horizontalScrollView = (HorizontalScrollView) findViewById(R.id.horizontalscrollview);  
  146.         // 調用方法實現   
  147.         initTextView();  
  148.         select(0);  
  149.         InItView();  
  150.   
  151.         viewPager.setAdapter(new PagerAdapter() {  
  152.             // 得到數目   
  153.             public int getCount() {  
  154.                 return pageViews.size();  
  155.             }  
  156.   
  157.             @Override  
  158.             public boolean isViewFromObject(View view, Object object) {  
  159.                 return view == object;  
  160.             }  
  161.   
  162.             @Override  
  163.             public int getItemPosition(Object object) {  
  164.                 // TODO Auto-generated method stub   
  165.                 return super.getItemPosition(object);  
  166.             }  
  167.   
  168.             @Override  
  169.             public void destroyItem(View view, int id, Object arg2) {  
  170.                 // TODO Auto-generated method stub   
  171.                 ((ViewPager) view).removeView(pageViews.get(id));  
  172.             }  
  173.   
  174.             // 獲取每一個item的id   
  175.             @Override  
  176.             public Object instantiateItem(View view, int id) {  
  177.                 ((ViewPager) view).addView(pageViews.get(id));  
  178.                 return pageViews.get(id);  
  179.             }  
  180.   
  181.         });  
  182.         // 頁面改變時候的監聽事件   
  183.         viewPager.setOnPageChangeListener(new OnPageChangeListener() {  
  184.   
  185.             @Override  
  186.             public void onPageSelected(int arg0) {  
  187.                 select(arg0);  
  188.             }  
  189.   
  190.             @Override  
  191.             public void onPageScrolled(int arg0, float arg1, int arg2) {  
  192.   
  193.             }  
  194.   
  195.             @Override  
  196.             public void onPageScrollStateChanged(int arg0) {  
  197.   
  198.             }  
  199.         });  
  200.     }  
  201.   
  202.     @Override  
  203.     public void onClick(View v) {  
  204.         select(v.getId());  
  205.     }  
  206.   
  207. }  

8.接著看看QQonline.java 的實現

  1. package com.wang;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.ContextMenu;  
  6. import android.view.View;  
  7. import android.view.Window;  
  8. import android.view.WindowManager;  
  9. import android.view.ContextMenu.ContextMenuInfo;  
  10. import android.widget.ExpandableListAdapter;  
  11. import android.widget.ExpandableListView;  
  12. import android.widget.Toast;  
  13. import android.widget.ExpandableListView.OnChildClickListener;  
  14. import android.widget.ExpandableListView.OnGroupClickListener;  
  15. import android.widget.ExpandableListView.OnGroupCollapseListener;  
  16. import android.widget.ExpandableListView.OnGroupExpandListener;  
  17.   
  18. public class QQonline extends Activity {  
  19.     // 創建一個上下文菜單的方法   
  20.     public void onCreateContextMenu(ContextMenu menu, View v,  
  21.             ContextMenuInfo menuInfo) {  
  22.   
  23.         super.onCreateContextMenu(menu, v, menuInfo);  
  24.   
  25.         // 一個垂直滾動的兩級列表。取得菜單項   
  26.         ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;  
  27.         // 獲得這個類型 的位置   
  28.         int type = ExpandableListView  
  29.                 .getPackedPositionType(info.packedPosition);  
  30.         // 取得所在組的索引   
  31.         int group = ExpandableListView  
  32.                 .getPackedPositionGroup(info.packedPosition);  
  33.         // 取得子菜單的索引   
  34.         int child = ExpandableListView  
  35.                 .getPackedPositionGroup(info.packedPosition);  
  36.   
  37.         Toast.makeText(QQonline.this,  
  38.                 "類型 =" + type + "  分組:" + group + "  子選項:" + child,  
  39.                 Toast.LENGTH_LONG).show();  
  40.   
  41.     }  
  42.   
  43.     private ExpandableListView eListView = null;  
  44.     private ExpandableListAdapter adapter = null;  
  45.   
  46.     @Override  
  47.     public void onCreate(Bundle savedInstanceState) {  
  48.   
  49.         // 去除標題,   
  50.         this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
  51.         // 取消狀態欄,充滿全屏   
  52.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  53.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  54.   
  55.         super.onCreate(savedInstanceState);  
  56.         super.setContentView(R.layout.qqonline);  
  57.   
  58.         // 實例化組件   
  59.         this.eListView = (ExpandableListView) findViewById(R.id.elistview);  
  60.   
  61.         // 聲明一個adapter對象   
  62.         adapter = new myExpendableadapler(this);  
  63.         // 設置適配器提供了數據   
  64.         this.eListView.setAdapter(this.adapter);  
  65.   
  66.         //  注冊一個上下文菜單顯示給定的視圖(多個視圖可以顯示上下文菜單)。   
  67.         super.registerForContextMenu(this.eListView);  
  68.   
  69.         // 設置點擊時候觸發的事件 1,子選項點擊事件 2。父選項單擊事件 3.分組打開事件 4.分組關閉事件   
  70.         this.eListView.setOnChildClickListener(new ChildClickListener());  
  71.         this.eListView.setOnGroupClickListener(new GroupClickListener());  
  72.         this.eListView.setOnGroupExpandListener(new GroupExpandListener());  
  73.         this.eListView.setOnGroupCollapseListener(new GroupCollapseListener());  
  74.   
  75.     }  
  76.   
  77.     // /1,子選項點擊事件   
  78.     private class ChildClickListener implements OnChildClickListener {  
  79.   
  80.         public boolean onChildClick(ExpandableListView parent, View v,  
  81.                 int groupPosition, int childPosition, long id) {  
  82.             Toast  
  83.                     .makeText(  
  84.                             QQonline.this,  
  85.                             "子選項被選中,所的組:" + groupPosition + "  子選項的位置:"  
  86.                                     + childPosition, Toast.LENGTH_LONG).show();  
  87.             return false;  
  88.         }  
  89.   
  90.     }  
  91.   
  92.     // 2。父選項單擊事件   
  93.     private class GroupClickListener implements OnGroupClickListener {  
  94.   
  95.         public boolean onGroupClick(ExpandableListView parent, View v,  
  96.                 int groupPosition, long id) {  
  97.             Toast.makeText(QQonline.this"分組選項被選中,所在組: " + groupPosition,  
  98.                     Toast.LENGTH_LONG).show();  
  99.             return false;  
  100.         }  
  101.   
  102.     }  
  103.   
  104.     // 3.分組打開事件   
  105.     private class GroupExpandListener implements OnGroupExpandListener {  
  106.   
  107.         public void onGroupExpand(int groupPosition) {  
  108.             // TODO Auto-generated method stub   
  109.             Toast.makeText(QQonline.this"打開分組,所在組:" + groupPosition,  
  110.                     Toast.LENGTH_LONG).show();  
  111.         }  
  112.   
  113.     }  
  114.   
  115.     // 4.分組關閉事件   
  116.     private class GroupCollapseListener implements OnGroupCollapseListener {  
  117.   
  118.         public void onGroupCollapse(int groupPosition) {  
  119.             Toast.makeText(QQonline.this"關閉分組,所在組:" + groupPosition,  
  120.                     Toast.LENGTH_LONG).show();  
  121.         }  
  122.   
  123.     }  
  124.   
  125. }  
9.接著需要myExpendableadapler.java
  1. package com.wang;  
  2.   
  3. import android.content.Context;  
  4. import android.view.Gravity;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.widget.AbsListView;  
  8. import android.widget.BaseExpandableListAdapter;  
  9. import android.widget.TextView;  
  10.   
  11. public class myExpendableadapler extends BaseExpandableListAdapter {  
  12.     // 組名稱   
  13.     private String[] group = new String[] { "在線好友""高中同學""南陽理工同學""寢室哥們" };  
  14.     // 子選項的名字   
  15.     private String[][] child = new String[][] {  
  16.             { "李彥宏""馬雲""雷軍""周鴻祎""唐駿""趙威威""李冕""馬海剛""李斌""劉洪剛",  
  17.                     "馬玉龍""劉慧敏""王文龍" },  
  18.             { "趙威威""李冕""馬海剛""李斌""劉洪剛""馬玉龍""劉慧敏""王文龍" },  
  19.             { "張紫陽""王亞光""劉一鳴""崔芳芳""董衛傑""劉永樂" },  
  20.             { "武雲冊""王俊偉""王傑""付永振""杜新峰""應志超" } };  
  21.     private Context context = null;  
  22.   
  23.     // 構造函數   
  24.     public myExpendableadapler(Context context) {  
  25.   
  26.         this.context = context;  
  27.     }  
  28.   
  29.     public Object getChild(int groupPosition, int childPosition) {  
  30.   
  31.         return this.child[groupPosition][childPosition];  
  32.     }  
  33.   
  34.     public long getChildId(int groupPosition, int childPosition) {  
  35.   
  36.         return childPosition;  
  37.     }  
  38.   
  39.     private TextView buildTextView() {  
  40.         // LayoutParams AbsListView擴展提供一個位置來保存視圖類型。   
  41.         AbsListView.LayoutParams params = new AbsListView.LayoutParams(  
  42.                 ViewGroup.LayoutParams.FILL_PARENT, 40);  
  43.   
  44.         TextView textView = new TextView(this.context);  
  45.         textView.setLayoutParams(params);  
  46.         // 大小   
  47.         textView.setTextSize(15.0f);  
  48.         textView.setGravity(Gravity.LEFT + 3);  
  49.         textView.setPadding(40833);  
  50.         return textView;  
  51.     }  
  52.   
  53.     public View getChildView(int groupPosition, int childPosition,  
  54.             boolean isLastChild, View convertView, ViewGroup parent) {  
  55.         TextView textView = new TextView(this.context);  
  56.         // 得到每組的子選項並轉換成字符串   
  57.         textView  
  58.                 .setText(this.getChild(groupPosition, childPosition).toString());  
  59.   
  60.         return textView;  
  61.     }  
  62.   
  63.     // 統計子選項的個數   
  64.     public int getChildrenCount(int groupPosition) {  
  65.         // TODO Auto-generated method stub   
  66.         return this.child[groupPosition].length;  
  67.     }  
  68.   
  69.     // 得到復選項的位置   
  70.     public Object getGroup(int groupPosition) {  
  71.         // TODO Auto-generated method stub   
  72.         return this.group[groupPosition];  
  73.     }  
  74.   
  75.     // 得到復選項的個數   
  76.     public int getGroupCount() {  
  77.         // TODO Auto-generated method stub   
  78.         return this.group.length;  
  79.     }  
  80.   
  81.     // 得到復選項的id   
  82.     public long getGroupId(int groupPosition) {  
  83.         // TODO Auto-generated method stub   
  84.         return groupPosition;  
  85.     }  
  86.   
  87.     public View getGroupView(int groupPosition, boolean isExpanded,  
  88.             View convertView, ViewGroup parent) {  
  89.         // TODO Auto-generated method stub   
  90.         TextView textView = this.buildTextView();  
  91.         textView.setText(this.getGroup(groupPosition).toString());  
  92.         return textView;  
  93.     }  
  94.   
  95.     // 是否子選項和父選項id是穩定在改變底層數據。   
  96.     public boolean hasStableIds() {  
  97.         // TODO Auto-generated method stub   
  98.         return true;  
  99.     }  
  100.   
  101.     // p判斷子選項是否可以選擇   
  102.     public boolean isChildSelectable(int groupPosition, int childPosition) {  
  103.         // TODO Auto-generated method stub   
  104.         return true;  
  105.     }  
  106.   
  107. }  

10.有兩個界面還沒有添加功能pullrefreshtest.java    

  1. package com.wang;  
  2.   
  3. import java.util.LinkedList;  
  4.   
  5. import com.wang.pullrefresh.MyListView;  
  6. import com.wang.pullrefresh.MyListView.OnRefreshListener;  
  7.   
  8. import android.app.Activity;  
  9. import android.os.AsyncTask;  
  10. import android.os.Bundle;  
  11. import android.view.LayoutInflater;  
  12. import android.view.View;  
  13. import android.view.ViewGroup;  
  14. import android.view.Window;  
  15. import android.view.WindowManager;  
  16. import android.widget.BaseAdapter;  
  17. import android.widget.TextView;  
  18.   
  19. public class pullrefreshtest extends Activity {  
  20.     private LinkedList<String> data;  
  21.     private BaseAdapter adapter;  
  22.   
  23.     public void onCreate(Bundle savedInstanceState) {  
  24.         // 去除標題欄   
  25.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  26.         // 設置全屏,取消狀態欄   
  27.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  28.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.pullrefresh);  
  31.   
  32.         data = new LinkedList<String>();  
  33.         for (int i = 40; i < 50; i++) {  
  34.             // 輸出list——item上的數據   
  35.             data.add(String.valueOf("暑假第" + i + "天,在南陽理工,想家ing ..."));  
  36.         }  
  37.   
  38.         final MyListView listView = (MyListView) findViewById(R.id.listView);  
  39.         adapter = new BaseAdapter() {  
  40.   
  41.             // 得到一個視圖,顯示在指定位置上的數據在數據集,可以創建一個視圖從XML布局文件   
  42.             public View getView(int position, View convertView, ViewGroup parent) {  
  43.                 // 上下文全局應用程序對象   
  44.                 convertView = LayoutInflater.from(getApplicationContext())  
  45.                         .inflate(R.layout.list_item, null);  
  46.                 // 實例化組件   
  47.                 TextView textView = (TextView) convertView  
  48.                         .findViewById(R.id.textView_item);  
  49.                 // 設置文本本內容   
  50.                 textView.setText(data.get(position));  
  51.                 return convertView;  
  52.             }  
  53.   
  54.             // 得到行相關聯id列表中指定的位置。   
  55.             public long getItemId(int position) {  
  56.                 return position;  
  57.             }  
  58.   
  59.             // 獲得相關的數據項中的指定位置的數據集   
  60.             public Object getItem(int position) {  
  61.                 return data.get(position);  
  62.             }  
  63.   
  64.             // 獲得項目在數據集適配器的個數。   
  65.             public int getCount() {  
  66.                 return data.size();  
  67.             }  
  68.   
  69.         };  
  70.   
  71.         listView.setAdapter(adapter);  
  72.   
  73.         listView.setonRefreshListener(new OnRefreshListener() {  
  74.             public void onRefresh() {  
  75.   
  76.                 new AsyncTask<Void, Void, Void>() {  
  77.                     // ...b表示多個參數   
  78.                     protected Void doInBackground(Void... params) {  
  79.                         try {  
  80.                             //    
  81.                             Thread.sleep(1000);  
  82.                         } catch (Exception e) {  
  83.                             e.printStackTrace();  
  84.                         }  
  85.   
  86.                         // 增加一條數據到list中   
  87.                         data.addFirst("刷新後內容:每天都是新的一天!!!,親!要努力奮斗哦!!!");  
  88.   
  89.                         return null;  
  90.                     }  
  91.   
  92.                     protected void onPostExecute(Void result) {  
  93.                         adapter.notifyDataSetChanged();  
  94.                         listView.onRefreshComplete();  
  95.                     }  
  96.   
  97.                 }.execute(null);  
  98.             }  
  99.         });  
  100.     }  
  101. }  

11.接著是下拉列表更新的實現過程MyListView.java

  1. package com.wang.pullrefresh;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.   
  6. import com.wang.R;  
  7.   
  8. import android.content.Context;  
  9. import android.util.AttributeSet;  
  10. import android.util.Log;  
  11. import android.view.LayoutInflater;  
  12. import android.view.MotionEvent;  
  13. import android.view.View;  
  14. import android.view.ViewGroup;  
  15. import android.view.View.MeasureSpec;  
  16. import android.view.animation.LinearInterpolator;  
  17. import android.view.animation.RotateAnimation;  
  18. import android.widget.AbsListView;  
  19. import android.widget.BaseAdapter;  
  20. import android.widget.ImageView;  
  21. import android.widget.LinearLayout;  
  22. import android.widget.ListView;  
  23. import android.widget.ProgressBar;  
  24. import android.widget.TextView;  
  25. import android.widget.AbsListView.OnScrollListener;  
  26.   
  27. public class MyListView extends ListView implements OnScrollListener {  
  28.   
  29.     private static final String TAG = "listview";  
  30.   
  31.     private final static int RELEASE_To_REFRESH = 0;  
  32.     private final static int PULL_To_REFRESH = 1;  
  33.     private final static int REFRESHING = 2;  
  34.     private final static int DONE = 3;  
  35.     private final static int LOADING = 4;  
  36.   
  37.     // 實際的padding的距離與界面上偏移距離的比例   
  38.     private final static int RATIO = 3;  
  39.   
  40.     private LayoutInflater inflater;  
  41.   
  42.     private LinearLayout headView;  
  43.   
  44.     private TextView tipsTextview;  
  45.     private TextView lastUpdatedTextView;  
  46.     private ImageView arrowImageView;  
  47.     private ProgressBar progressBar;  
  48.   
  49.     private RotateAnimation animation;  
  50.     private RotateAnimation reverseAnimation;  
  51.   
  52.     // 用於保證startY的值在一個完整的touch事件中只被記錄一次   
  53.     private boolean isRecored;  
  54.   
  55.     private int headContentWidth;  
  56.     private int headContentHeight;  
  57.   
  58.     private int startY;  
  59.     private int firstItemIndex;  
  60.   
  61.     private int state;  
  62.   
  63.     private boolean isBack;  
  64.   
  65.     private OnRefreshListener refreshListener;  
  66.   
  67.     private boolean isRefreshable;  
  68.   
  69.     public MyListView(Context context) {  
  70.         super(context);  
  71.         // 調用下面初始化的函數   
  72.         init(context);  
  73.     }  
  74.   
  75.     public MyListView(Context context, AttributeSet attrs) {  
  76.         super(context, attrs);  
  77.         // 調用下面初始化的函數   
  78.         init(context);  
  79.     }  
  80.   
  81.     private void init(Context context) {  
  82.   
  83.         // 獲得LayoutInflater從給定的上下文。   
  84.         inflater = LayoutInflater.from(context);  
  85.   
  86.         // 實例化布局XML文件轉換成相應的視圖對象。   
  87.         headView = (LinearLayout) inflater.inflate(R.layout.refresh, null);  
  88.   
  89.         arrowImageView = (ImageView) headView  
  90.                 .findViewById(R.id.head_arrowImageView);  
  91.         // 設置最小寬度 和高度   
  92.         arrowImageView.setMinimumWidth(70);  
  93.         arrowImageView.setMinimumHeight(50);  
  94.         // 實例化布局XML文件轉換成相應的視圖對象。   
  95.         progressBar = (ProgressBar) headView  
  96.                 .findViewById(R.id.head_progressBar);  
  97.         tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);  
  98.         lastUpdatedTextView = (TextView) headView  
  99.                 .findViewById(R.id.head_lastUpdatedTextView);  
  100.   
  101.         // 調用下拉刷新的方法   
  102.         measureView(headView);  
  103.         // d得到原始高度和寬度   
  104.         headContentHeight = headView.getMeasuredHeight();  
  105.         headContentWidth = headView.getMeasuredWidth();  
  106.   
  107.         // 設置填充。視圖可能添加的空間要求顯示滾動條,這取決於風格和知名度的滾動條   
  108.         headView.setPadding(0, -1 * headContentHeight, 00);  
  109.         headView.invalidate();  
  110.   
  111.         // 標簽用來識別一個日志消息的來源。標識類或活動日志調用發生   
  112.         Log.v("size""width:" + headContentWidth + " height:"  
  113.                 + headContentHeight);  
  114.   
  115.         // 添加一個固定視圖出現在列表的頂部   
  116.         addHeaderView(headView, nullfalse);  
  117.         // 設置監聽事件   
  118.         setOnScrollListener(this);  
  119.   
  120.         // 動畫效果實現下拉和松開時候圖片的 180度 旋轉 注意0, -180,和他是有區別的 -180, 0,   
  121.         animation = new RotateAnimation(0, -180,  
  122.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
  123.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  124.         // 設置加速度曲線為這個動畫。默認值為一個線性插值。   
  125.         animation.setInterpolator(new LinearInterpolator());  
  126.         animation.setDuration(300);  
  127.         // 如果fillAfter是真的,轉換,該動畫執行完成時將會持續下去   
  128.         animation.setFillAfter(true);  
  129.   
  130.         reverseAnimation = new RotateAnimation(-1800,  
  131.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
  132.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  133.         // 設置加速度曲線為這個動畫。默認值為一個線性插值。   
  134.         reverseAnimation.setInterpolator(new LinearInterpolator());  
  135.         reverseAnimation.setDuration(300);  
  136.         // 如果fillAfter是真的,轉換,該動畫執行完成時將會持續下去   
  137.         reverseAnimation.setFillAfter(true);  
  138.   
  139.         // 設置狀態   
  140.         state = DONE;  
  141.         // 設置不可刷新狀態   
  142.         isRefreshable = false;  
  143.     }  
  144.   
  145.     // 回調方法時要調用的列表或網格已經滾動。這將完成之後調用的滾動方法   
  146.     public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,  
  147.             int arg3) {  
  148.         firstItemIndex = firstVisiableItem;  
  149.     }  
  150.   
  151.     /* 
  152.      * 回調方法調用而列表視圖或網格視圖被滾動。 如果這個視圖被滾動,將調用此方法在接下來的一局畫卷的呈現 * 
  153.      */  
  154.     public void onScrollStateChanged(AbsListView arg0, int arg1) {  
  155.     }  
  156.   
  157.     // 觸摸事件監聽   
  158.     public boolean onTouchEvent(MotionEvent event) {  
  159.   
  160.         // 判斷是否可以刷新   
  161.         if (isRefreshable) {  
  162.             // 根據動作相應不同的方法   
  163.             switch (event.getAction()) {  
  164.   
  165.             // 當按住屏幕向下拉屏幕的時候   
  166.             case MotionEvent.ACTION_DOWN:  
  167.                 if (firstItemIndex == 0 && !isRecored) {  
  168.                     isRecored = true;  
  169.                     startY = (int) event.getY();  
  170.                     Log.v(TAG, "在下拉的時候記錄當前位置‘");  
  171.                 }  
  172.                 break;  
  173.   
  174.             // 當按住屏幕向上松屏幕的時候   
  175.             case MotionEvent.ACTION_UP:  
  176.   
  177.                 if (state != REFRESHING && state != LOADING) {  
  178.                     if (state == DONE) {  
  179.   
  180.                     }  
  181.                     if (state == PULL_To_REFRESH) {  
  182.                         state = DONE;  
  183.                         changeHeaderViewByState();  
  184.   
  185.                         Log.v(TAG, "由下拉刷新狀態,到done狀態");  
  186.                     }  
  187.                     if (state == RELEASE_To_REFRESH) {  
  188.                         state = REFRESHING;  
  189.                         changeHeaderViewByState();  
  190.                         onRefresh();  
  191.   
  192.                         Log.v(TAG, "由松開刷新狀態,到done狀態");  
  193.                     }  
  194.                 }  
  195.   
  196.                 isRecored = false;  
  197.                 isBack = false;  
  198.   
  199.                 break;  
  200.   
  201.             // 當按住屏幕移動時候   
  202.             case MotionEvent.ACTION_MOVE:  
  203.                 int tempY = (int) event.getY();  
  204.   
  205.                 if (!isRecored && firstItemIndex == 0) {  
  206.                     Log.v(TAG, "在move時候記錄下位置");  
  207.                     isRecored = true;  
  208.                     startY = tempY;  
  209.                 }  
  210.   
  211.                 if (state != REFRESHING && isRecored && state != LOADING) {  
  212.   
  213.                     /*** 
  214.                      * , 當前的位置一直是在head,否則如果當列表超出屏幕的話, 當在上推的時候,列表會同時進行滾動 
  215.                      */  
  216.                     // 可以松手去刷新了   
  217.                     if (state == RELEASE_To_REFRESH) {  
  218.   
  219.                         setSelection(0);  
  220.   
  221.                         // 往上推了,推到了屏幕足夠掩蓋head的程度,但是還沒有推到全部掩蓋的地步   
  222.                         if (((tempY - startY) / RATIO < headContentHeight)  
  223.                                 && (tempY - startY) > 0) {  
  224.                             state = PULL_To_REFRESH;  
  225.                             changeHeaderViewByState();  
  226.   
  227.                             Log.v(TAG, "由松開刷新狀態轉變到下拉刷新狀態");  
  228.                         }  
  229.                         // 一下子推到頂了   
  230.                         else if (tempY - startY <= 0) {  
  231.                             state = DONE;  
  232.                             // 調用改變時候的方法,更新UI   
  233.                             changeHeaderViewByState();  
  234.   
  235.                             Log.v(TAG, "由松開刷新狀態轉變到done狀態");  
  236.                         } else {  
  237.                         }  
  238.                     }  
  239.                     // 還沒有到達顯示松開刷新的時候   
  240.                     if (state == PULL_To_REFRESH) {  
  241.   
  242.                         setSelection(0);  
  243.   
  244.                         // 下拉到可以進入RELEASE_TO_REFRESH的狀態   
  245.                         if ((tempY - startY) / RATIO >= headContentHeight) {  
  246.                             state = RELEASE_To_REFRESH;  
  247.                             isBack = true;  
  248.                             // 調用改變時候的方法,更新UI   
  249.                             changeHeaderViewByState();  
  250.   
  251.                             Log.v(TAG, "由done或者下拉刷新狀態轉變到松開刷新");  
  252.                         }  
  253.                         // 上推到頂了   
  254.                         else if (tempY - startY <= 0) {  
  255.                             state = DONE;  
  256.                             // 調用改變時候的方法,更新UI   
  257.                             changeHeaderViewByState();  
  258.   
  259.                             Log.v(TAG, "由DOne或者下拉刷新狀態轉變到done狀態");  
  260.                         }  
  261.                     }  
  262.   
  263.                     // done狀態下   
  264.                     if (state == DONE) {  
  265.                         if (tempY - startY > 0) {  
  266.                             state = PULL_To_REFRESH;  
  267.                             // 調用改變時候的方法,更新UI   
  268.                             changeHeaderViewByState();  
  269.                         }  
  270.                     }  
  271.   
  272.                     // 更新headView的size   
  273.                     if (state == PULL_To_REFRESH) {  
  274.                         headView.setPadding(0, -1 * headContentHeight  
  275.                                 + (tempY - startY) / RATIO, 00);  
  276.   
  277.                     }  
  278.   
  279.                     // 更新headView的paddingTop   
  280.                     if (state == RELEASE_To_REFRESH) {  
  281.                         headView.setPadding(0, (tempY - startY) / RATIO  
  282.                                 - headContentHeight, 00);  
  283.                     }  
  284.   
  285.                 }  
  286.   
  287.                 break;  
  288.             }  
  289.         }  
  290.   
  291.         return super.onTouchEvent(event);  
  292.     }  
  293.   
  294.     // 當狀態改變時候,調用該方法,以更新界面   
  295.     private void changeHeaderViewByState() {  
  296.         // 根據當前的狀態進行判斷   
  297.         switch (state) {  
  298.   
  299.         // 下拉時候,松開既可刷新   
  300.         case RELEASE_To_REFRESH:  
  301.             // 設置視圖 VISIBLE 可見 ,GONE 不可見   
  302.             arrowImageView.setVisibility(View.VISIBLE);  
  303.             progressBar.setVisibility(View.GONE);  
  304.             tipsTextview.setVisibility(View.VISIBLE);  
  305.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  306.   
  307.             // 現在開始指定的動畫。   
  308.             arrowImageView.clearAnimation();  
  309.             arrowImageView.startAnimation(animation);  
  310.   
  311.             tipsTextview.setText("松開既可刷新");  
  312.   
  313.             Log.v(TAG, "當前狀態,松開即可刷新");  
  314.             break;  
  315.   
  316.         // 開始時候,下拉刷新   
  317.         case PULL_To_REFRESH:  
  318.             // 設置視圖 VISIBLE 可見 ,GONE 不可見   
  319.             progressBar.setVisibility(View.GONE);  
  320.             tipsTextview.setVisibility(View.VISIBLE);  
  321.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  322.             // 現在開始指定的動畫。   
  323.             arrowImageView.clearAnimation();  
  324.             arrowImageView.setVisibility(View.VISIBLE);  
  325.   
  326.             if (isBack) {  
  327.                 isBack = false;  
  328.                 // 現在開始指定的動畫。   
  329.                 arrowImageView.clearAnimation();  
  330.                 arrowImageView.startAnimation(reverseAnimation);  
  331.   
  332.                 tipsTextview.setText("下拉刷新");  
  333.             } else {  
  334.                 tipsTextview.setText("下拉刷新");  
  335.             }  
  336.             Log.v(TAG, "當前狀態,下拉刷新");  
  337.             break;  
  338.   
  339.         case REFRESHING:  
  340.   
  341.             headView.setPadding(0000);  
  342.             // 設置視圖 VISIBLE 可見 ,GONE 不可見   
  343.             progressBar.setVisibility(View.VISIBLE);  
  344.             // 現在開始指定的動畫。   
  345.             arrowImageView.clearAnimation();  
  346.             arrowImageView.setVisibility(View.GONE);  
  347.             tipsTextview.setText("正在刷新...");  
  348.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  349.   
  350.             Log.v(TAG, "當前狀態,正在刷新...");  
  351.             break;  
  352.         case DONE:  
  353.             // 設置填充。視圖可能添加的空間要求顯示滾動條   
  354.             headView.setPadding(0, -1 * headContentHeight, 00);  
  355.             // 設置視圖 VISIBLE 可見 ,GONE 不可見   
  356.             progressBar.setVisibility(View.GONE);  
  357.             // 現在開始指定的動畫。   
  358.             arrowImageView.clearAnimation();  
  359.             arrowImageView.setImageResource(R.drawable.down);  
  360.             tipsTextview.setText("下拉刷新");  
  361.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  362.   
  363.             Log.v(TAG, "當前狀態");  
  364.             break;  
  365.         }  
  366.     }  
  367.   
  368.     public void setonRefreshListener(OnRefreshListener refreshListener) {  
  369.         this.refreshListener = refreshListener;  
  370.         isRefreshable = true;  
  371.     }  
  372.   
  373.     public interface OnRefreshListener {  
  374.         public void onRefresh();  
  375.     }  
  376.   
  377.     // 設置更新時間   
  378.     public void onRefreshComplete() {  
  379.         state = DONE;  
  380.         //   
  381.         SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");  
  382.         String date = format.format(new Date());  
  383.         lastUpdatedTextView.setText("最近更新:" + date);  
  384.         changeHeaderViewByState();  
  385.     }  
  386.   
  387.     private void onRefresh() {  
  388.         if (refreshListener != null) {  
  389.             refreshListener.onRefresh();  
  390.         }  
  391.     }  
  392.   
  393.     // 下拉刷新的   
  394.     private void measureView(View child) {  
  395.         // v這組布局參數寬度和高度   
  396.         ViewGroup.LayoutParams p = child.getLayoutParams();  
  397.         if (p == null) {  
  398.             // 創建一個新組布局參數指定的寬度(填充)和高度(包裹)。   
  399.             p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,  
  400.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  401.         }  
  402.   
  403.         // d得到childWidthSpec(高度或寬度)的子視圖   
  404.         int childWidthSpec = ViewGroup.getChildMeasureSpec(00 + 0, p.width);  
  405.         int lpHeight = p.height;  
  406.         int childHeightSpec;  
  407.         if (lpHeight > 0) {  
  408.             // 創建一個測量規范基於所提供的大小和模式   
  409.             childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,  
  410.                     MeasureSpec.EXACTLY);  
  411.         } else {  
  412.             childHeightSpec = MeasureSpec.makeMeasureSpec(0,  
  413.                     MeasureSpec.UNSPECIFIED);  
  414.         }  
  415.         // 找出一個視圖應該多大。父供應約束信息在寬度和高度參數   
  416.         child.measure(childWidthSpec, childHeightSpec);  
  417.     }  
  418.   
  419.     public void setAdapter(BaseAdapter adapter) {  
  420.         // 設置最近刷新的時間   
  421.         SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");  
  422.         String date = format.format(new Date());  
  423.         lastUpdatedTextView.setText("最近更新:" + date);  
  424.         super.setAdapter(adapter);  
  425.     }  
  426.   
  427. }  

12.接著是沒有添加聊天功能的main3.java

  1. package com.wang;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.ImageView;  
  6.   
  7. public class main3 extends Activity {  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         // TODO Auto-generated method stub   
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.main3);  
  12.     }  
  13.   
  14. }  
13.親,由於用到Activity,要注意注冊哦!!
  1. <activity android:name=".pullrefreshtest"></activity>  
  2.       <activity android:name=".QQonline"></activity>  
  3.       <activity android:name=".main3"></activity>  

14.最後,還有一個重要的問題,本程序需要第三方jar包的支持,所以呢還需要導入第三方android-support-v4.jar包, 不會的參考 http://www.linuxidc.com/Linux/2012-08/67213.htm

下載地址

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2012年資料/8月/3日/Android模仿QQ的左右滑動切換界面和下拉更新的效果/android-support-v4.jar包

15,這樣過後就可以看到運行效果咯: 第一張是下拉刷新時候的界面,第二張是松開即可刷新時候的圖片,第三張是刷新後的內容,第四張的QQ聯系人的界面,第五張是還沒有完善聊天消息的界面,第六張是左右滑動切換界面的實現效果

Copyright © Linux教程網 All Rights Reserved