分享

android项目剖解之ViewPager+Fragment 实现tabhost效果

 ccccshq 2015-05-09

  项目中需要用到底栏导航栏,滑动或者点击会切换上面的视图,如图:



这个效果使用Viewpager+Fragmen实现是主流方案,加入你之前对fragment不太了解,可以先看android之Fragment(官网资料翻译)

整个文件如下:


好了废话少说,先上布局文件:main.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas./apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.     <android.support.v4.view.ViewPager  
  7.         android:id="@+id/vPager"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="0dp"  
  10.         android:layout_gravity="center"  
  11.         android:layout_weight="1.0"  
  12.         android:background="#000000"  
  13.         android:flipInterval="30"  
  14.         android:persistentDrawingCache="animation" />  
  15.   
  16.     <LinearLayout  
  17.         android:layout_width="match_parent"  
  18.         android:layout_height="wrap_content"  
  19.         android:orientation="vertical" >  
  20.   
  21.         <LinearLayout  
  22.             android:id="@+id/linearLayout1"  
  23.             android:layout_width="fill_parent"  
  24.             android:layout_height="wrap_content"  
  25.             android:background="@color/coral"  
  26.             android:paddingBottom="5dip"  
  27.             android:paddingTop="10dip" >  
  28.   
  29.             <TextView  
  30.                 android:id="@+id/tv_tab_1"  
  31.                 android:layout_width="fill_parent"  
  32.                 android:layout_height="fill_parent"  
  33.                 android:layout_weight="1.0"  
  34.                 android:gravity="center"  
  35.                 android:text="@string/tab_1"  
  36.                 android:textColor="@color/white"  
  37.                 android:textSize="18sp" />  
  38.   
  39.             <TextView  
  40.                 android:id="@+id/tv_tab_2"  
  41.                 android:layout_width="fill_parent"  
  42.                 android:layout_height="fill_parent"  
  43.                 android:layout_weight="1.0"  
  44.                 android:gravity="center"  
  45.                 android:text="@string/tab_2"  
  46.                 android:textColor="@color/lightwhite"  
  47.                 android:textSize="18sp" />  
  48.   
  49.             <TextView  
  50.                 android:id="@+id/tv_tab_3"  
  51.                 android:layout_width="fill_parent"  
  52.                 android:layout_height="fill_parent"  
  53.                 android:layout_weight="1.0"  
  54.                 android:gravity="center"  
  55.                 android:text="@string/tab_3"  
  56.                 android:textColor="@color/lightwhite"  
  57.                 android:textSize="18sp" />  
  58.   
  59.             <TextView  
  60.                 android:id="@+id/tv_tab_4"  
  61.                 android:layout_width="fill_parent"  
  62.                 android:layout_height="fill_parent"  
  63.                 android:layout_weight="1.0"  
  64.                 android:gravity="center"  
  65.                 android:text="@string/tab_4"  
  66.                 android:textColor="@color/lightwhite"  
  67.                 android:textSize="18sp" />  
  68.         </LinearLayout>  
  69.   
  70.         <LinearLayout  
  71.             android:layout_width="match_parent"  
  72.             android:layout_height="wrap_content"  
  73.             android:layout_gravity="bottom"  
  74.             android:orientation="vertical"  
  75.             android:paddingBottom="3dip" >  
  76.   
  77.             <ImageView  
  78.                 android:id="@+id/iv_bottom_line"  
  79.                 android:layout_width="40dip"  
  80.                 android:layout_height="2dip"  
  81.                 android:layout_marginLeft="20dip"  
  82.                 android:scaleType="matrix"  
  83.                 android:src="#fff" />  
  84.         </LinearLayout>  
  85.     </LinearLayout>  
  86. </LinearLayout>  

其实上面的整个布局非常简单,就是ViewPager+LinearLayout,写完mian后,后面写lay1,lay2,lay3等文件,都只是普通布局文件,就不贴代码了,回头可以下载代码查看。

接下来是 MainActivity.java

  1. package com.vatty.activity;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7.   
  8. import android.content.res.Resources;  
  9. import android.os.Bundle;  
  10. import android.support.v4.app.Fragment;  
  11. import android.support.v4.app.FragmentActivity;  
  12. import android.support.v4.view.ViewPager;  
  13. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  14. import android.util.DisplayMetrics;  
  15. import android.util.Log;  
  16. import android.view.View;  
  17. import android.view.Window;  
  18. import android.view.animation.Animation;  
  19. import android.view.animation.TranslateAnimation;  
  20. import android.widget.ImageView;  
  21. import android.widget.TextView;  
  22.   
  23. /** 
  24.  *  
  25.  * MainActivity.java 
  26.  * @author mayi 
  27.  * 2014-8-2 下午11:51:28 
  28.  * 
  29.  */  
  30. public class MainActivity extends FragmentActivity {  
  31.     private static final String TAG = "MainActivity";  
  32.     private ViewPager mPager;  
  33.     private ArrayList<Fragment> fragmentsList;  
  34.     private ImageView ivBottomLine;  
  35.     private TextView tv_tab_1, tv_tab_2, tv_tab_3, tv_tab_4;  
  36.   
  37.     private int currIndex = 0;  
  38.     private int bottomLineWidth;  
  39.     private int offset = 0;  
  40.     private int position_one;  
  41.     private int position_two;  
  42.     private int position_three;  
  43.     private Resources resources;  
  44.   
  45.     @Override  
  46.     public void onCreate(Bundle savedInstanceState) {  
  47.         super.onCreate(savedInstanceState);  
  48.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  49.           
  50.         setContentView(R.layout.main);  
  51.           
  52.         resources = getResources();  
  53.          
  54.         InitWidth();  
  55.           
  56.         InitTextView();  
  57.           
  58.         InitViewPager();  
  59.     }  
  60.       
  61.     /** 
  62.      * 获取底栏中的控件并添加监听事件 
  63.      */  
  64.     private void InitTextView() {  
  65.         tv_tab_1 = (TextView) findViewById(R.id.tv_tab_1);  
  66.         tv_tab_2 = (TextView) findViewById(R.id.tv_tab_2);  
  67.         tv_tab_3 = (TextView) findViewById(R.id.tv_tab_3);  
  68.         tv_tab_4 = (TextView) findViewById(R.id.tv_tab_4);  
  69.   
  70.         tv_tab_1.setOnClickListener(new MyOnClickListener(0));  
  71.         tv_tab_2.setOnClickListener(new MyOnClickListener(1));  
  72.         tv_tab_3.setOnClickListener(new MyOnClickListener(2));  
  73.         tv_tab_4.setOnClickListener(new MyOnClickListener(3));  
  74.     }  
  75.     /** 
  76.      * 初始化ViewPager 
  77.      */  
  78.     private void InitViewPager() {  
  79.         //获取布局中的viewpager控件  
  80.         mPager = (ViewPager) findViewById(R.id.vPager);  
  81.         //Fragment容器  
  82.         fragmentsList = new ArrayList<Fragment>();  
  83.            
  84.         Map<String, Object> paramMap = new HashMap<String, Object>();  
  85.         paramMap.put("userid","小洪");  
  86.         paramMap.put("age",23);  
  87.           
  88.           
  89.         Map<String, Object> paramMap2 = new HashMap<String, Object>();  
  90.         paramMap2.put("userid","vatty");  
  91.         paramMap2.put("age",24);  
  92.           
  93.         Map<String, Object> paramMap3 = new HashMap<String, Object>();  
  94.         paramMap3.put("userid","小明");  
  95.         paramMap3.put("age",25);  
  96.           
  97.           
  98.         Map<String, Object> paramMap4 = new HashMap<String, Object>();  
  99.         paramMap4.put("userid","hongshengpeng.com");  
  100.         paramMap4.put("age",26);  
  101.          
  102.         //生成每个tab对应的fragment  
  103.         Fragment activityfragment = TestFragment.newInstance("Hello Activity.",paramMap);  
  104.         Fragment groupFragment = TestFragment.newInstance("Hello Group.",paramMap2);  
  105.         Fragment friendsFragment=TestFragment.newInstance("Hello Friends.",paramMap3);  
  106.         Fragment chatFragment=TestFragment.newInstance("Hello Chat.",paramMap4);  
  107.         //添加到Fragment容器中  
  108.         fragmentsList.add(activityfragment);  
  109.         fragmentsList.add(groupFragment);  
  110.         fragmentsList.add(friendsFragment);  
  111.         fragmentsList.add(chatFragment);  
  112.         //给ViewPager添加适配器  
  113.         mPager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager(), fragmentsList));  
  114.         //设置默认的视图为第0个  
  115.         mPager.setCurrentItem(0);  
  116.         //给Viewpager添加监听事件  
  117.         mPager.setOnPageChangeListener(new MyOnPageChangeListener());  
  118.     }  
  119.       
  120.     /** 
  121.      *  初始化底栏,获取相应宽度信息 
  122.      */  
  123.     private void InitWidth() {  
  124.         ivBottomLine = (ImageView) findViewById(R.id.iv_bottom_line);  
  125.         //获取底栏白色滑动线的宽度  
  126.         bottomLineWidth = ivBottomLine.getLayoutParams().width;  
  127.         Log.d(TAG, "cursor imageview width=" + bottomLineWidth);  
  128.           
  129.         //获取屏幕宽度  
  130.         DisplayMetrics dm = new DisplayMetrics();  
  131.         getWindowManager().getDefaultDisplay().getMetrics(dm);  
  132.         int screenW = dm.widthPixels;  
  133.         //屏幕分4份,计算出每份中白色滑条外的间隔距离  
  134.         offset = (int) ((screenW / 4.0 - bottomLineWidth) / 2);  
  135.         Log.i("MainActivity", "offset=" + offset);  
  136.           
  137.         //计算出底栏的位置  
  138.         position_one = (int) (screenW / 4.0);  
  139.         position_two = position_one * 2;  
  140.         position_three = position_one * 3;  
  141.     }  
  142.       
  143.       
  144.     /** 
  145.      * 自定义监听类   如此定义监听类,可以实现共用。 
  146.      * @author Administrator 
  147.      * 
  148.      */  
  149.     public class MyOnClickListener implements View.OnClickListener {  
  150.         private int index = 0;  
  151.   
  152.         public MyOnClickListener(int i) {  
  153.             index = i;  
  154.         }  
  155.   
  156.         @Override  
  157.         public void onClick(View v) {  
  158.             //设置ViewPager的当前view  
  159.             mPager.setCurrentItem(index);  
  160.         }  
  161.     };  
  162.       
  163.     /** 
  164.      * 页面滑动监听 
  165.      * @author Administrator 
  166.      * 
  167.      */  
  168.     public class MyOnPageChangeListener implements OnPageChangeListener {  
  169.   
  170.         @Override  
  171.         public void onPageSelected(int index) {  
  172.             //动画  
  173.             Animation animation = null;  
  174.             switch (index) {  
  175.             case 0:  
  176.                 if (currIndex == 1) {  
  177.                     //代码生成滑动动画  
  178.                     animation = new TranslateAnimation(position_one, 0, 0, 0);  
  179.                     //改变tv_tab_2的颜色值,使其没有选中的效果  
  180.                     tv_tab_2.setTextColor(resources.getColor(R.color.lightwhite));  
  181.                 } else if (currIndex == 2) {  
  182.                     animation = new TranslateAnimation(position_two, 0, 0, 0);  
  183.                     tv_tab_3.setTextColor(resources.getColor(R.color.lightwhite));  
  184.                 } else if (currIndex == 3) {  
  185.                     animation = new TranslateAnimation(position_three, 0, 0, 0);  
  186.                     tv_tab_4.setTextColor(resources.getColor(R.color.lightwhite));  
  187.                 }  
  188.                 //改变tv_tab_1的颜色值,使其有选中的效果  
  189.                 tv_tab_1.setTextColor(resources.getColor(R.color.white));  
  190.                 break;  
  191.             case 1:  
  192.                 if (currIndex == 0) {  
  193.                     animation = new TranslateAnimation(0, position_one, 0, 0);  
  194.                     tv_tab_1.setTextColor(resources.getColor(R.color.lightwhite));  
  195.                 } else if (currIndex == 2) {  
  196.                     animation = new TranslateAnimation(position_two, position_one, 0, 0);  
  197.                     tv_tab_3.setTextColor(resources.getColor(R.color.lightwhite));  
  198.                 } else if (currIndex == 3) {  
  199.                     animation = new TranslateAnimation(position_three, position_one, 0, 0);  
  200.                     tv_tab_4.setTextColor(resources.getColor(R.color.lightwhite));  
  201.                 }  
  202.                 tv_tab_2.setTextColor(resources.getColor(R.color.white));  
  203.                 break;  
  204.             case 2:  
  205.                 if (currIndex == 0) {  
  206.                     animation = new TranslateAnimation(0, position_two, 0, 0);  
  207.                     tv_tab_1.setTextColor(resources.getColor(R.color.lightwhite));  
  208.                 } else if (currIndex == 1) {  
  209.                     animation = new TranslateAnimation(position_one, position_two, 0, 0);  
  210.                     tv_tab_2.setTextColor(resources.getColor(R.color.lightwhite));  
  211.                 } else if (currIndex == 3) {  
  212.                     animation = new TranslateAnimation(position_three, position_two, 0, 0);  
  213.                     tv_tab_4.setTextColor(resources.getColor(R.color.lightwhite));  
  214.                 }  
  215.                 tv_tab_3.setTextColor(resources.getColor(R.color.white));  
  216.                 break;  
  217.             case 3:  
  218.                 if (currIndex == 0) {  
  219.                     animation = new TranslateAnimation(0, position_three, 0, 0);  
  220.                     tv_tab_1.setTextColor(resources.getColor(R.color.lightwhite));  
  221.                 } else if (currIndex == 1) {  
  222.                     animation = new TranslateAnimation(position_one, position_three, 0, 0);  
  223.                     tv_tab_2.setTextColor(resources.getColor(R.color.lightwhite));  
  224.                 } else if (currIndex == 2) {  
  225.                     animation = new TranslateAnimation(position_two, position_three, 0, 0);  
  226.                     tv_tab_3.setTextColor(resources.getColor(R.color.lightwhite));  
  227.                 }  
  228.                 tv_tab_4.setTextColor(resources.getColor(R.color.white));  
  229.                 break;  
  230.             }  
  231.             //记录当前的页面位置  
  232.             currIndex = index;  
  233.             //动画播放完后,保持结束时的状态  
  234.             animation.setFillAfter(true);  
  235.             //动画持续时间  
  236.             animation.setDuration(300);  
  237.             //底栏滑动白线开始动画  
  238.             ivBottomLine.startAnimation(animation);  
  239.         }  
  240.   
  241.         @Override  
  242.         public void onPageScrolled(int arg0, float arg1, int arg2) {  
  243.           
  244.         }  
  245.   
  246.         @Override  
  247.         public void onPageScrollStateChanged(int arg0) {  
  248.           
  249.         }  
  250.     }  
  251. }  

整个代码中就是做初始化准备作用,加载layout,拿到各个控件,设置adapter,添加监听等。代码中有比较详细的注释,这里不再讲。

接下来就是Fragment模块:

TestFragment.java

  1. package com.vatty.activity;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Map;  
  5.   
  6. import android.os.Bundle;  
  7. import android.support.v4.app.Fragment;  
  8. import android.view.LayoutInflater;  
  9. import android.view.View;  
  10. import android.view.ViewGroup;  
  11. import android.widget.ListView;  
  12.   
  13. import com.vatty.adapter.ContactAdapter;  
  14. import com.vatty.model.Contact;  
  15.   
  16. /** 
  17.  *  
  18.  * TestFragment.java 
  19.  * @author mayi 
  20.  * 2014-8-2 下午11:54:19 
  21.  * 
  22.  */  
  23. public class TestFragment extends Fragment {  
  24.     private static final String TAG = "TestFragment";  
  25.     private Map<String, Object> maplist;  
  26.   
  27.     /** 
  28.      * 获取新的Fragment 
  29.      * @param s 
  30.      * @param map 
  31.      * @return 
  32.      */  
  33.     static TestFragment newInstance(String s, Map<String, Object> map) {  
  34.         TestFragment newFragment = new TestFragment();  
  35.         final SerializableMap myMap = new SerializableMap();  
  36.         myMap.setMap(map);  
  37.         //Bundle 存储数据  
  38.         Bundle bundle = new Bundle();  
  39.         bundle.putSerializable("map", myMap);  
  40.         //Fragment传送数据  
  41.         newFragment.setArguments(bundle);  
  42.         return newFragment;  
  43.   
  44.     }  
  45.   
  46.     @Override  
  47.     public void onCreate(Bundle savedInstanceState) {  
  48.         super.onCreate(savedInstanceState);  
  49. //      Log.d(TAG, "TestFragment-----onCreate");  
  50.         //获取Fragment传送的数据  
  51.         Bundle bundle = getArguments();  
  52.         SerializableMap serializableMap = (SerializableMap) bundle.get("map");  
  53.           
  54.         maplist = serializableMap.getMap();  
  55.     }  
  56.   
  57.     @Override  
  58.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  59.             Bundle savedInstanceState) {  
  60. //      Log.d(TAG, "TestFragment-----onCreateView");  
  61.           
  62.         //加载要在此Fragment中显示的layout(布局文件)  
  63.         View view = inflater.inflate(R.layout.lay1, container, false);  
  64.           
  65.         //-------------------------------以下的根据自己项目的需要做开发----------------------------------------------  
  66.         //获取layout中的控件  
  67.         ListView lv = (ListView) view.findViewById(R.id.listView3);  
  68.           
  69.         //getActivity().getApplicationContext()方法  获取Context  
  70.         ContactAdapter hc = new ContactAdapter(getActivity().getApplicationContext(), getContact());  
  71.         lv.setAdapter(hc);  
  72.         lv.setCacheColorHint(0);  
  73.   
  74.         return view;  
  75.   
  76.     }  
  77.       
  78.     private ArrayList<Contact> getContact() {  
  79.         ArrayList<Contact> hcList = new ArrayList<Contact>();  
  80.   
  81.         for (int i = 0; i < 10; i++) {  
  82.             Contact c0 = new Contact();  
  83.             c0.setTxPath(R.drawable.more_game + "");  
  84.   
  85.             c0.setName(maplist.get("userid") + "  年龄:" + maplist.get("age"));  
  86.             hcList.add(c0);  
  87.         }  
  88.   
  89.         return hcList;  
  90.     }  
  91.       
  92.     @Override  
  93.     public void onDestroy() {  
  94.         super.onDestroy();  
  95. //      Log.d(TAG, "TestFragment-----onDestroy");  
  96.     }  
  97.   
  98. }  

至此,整个demo中主要的代码模块已经展现了,其他类似adapter的,就跟我们平常开发的没多大区别,大家可以去下载代码查看。

DEMO下载

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多