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

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



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

整个文件如下:


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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <android.support.v4.view.ViewPager
        android:id="@+id/vPager"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_weight="1.0"
        android:background="#000000"
        android:flipInterval="30"
        android:persistentDrawingCache="animation" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@color/coral"
            android:paddingBottom="5dip"
            android:paddingTop="10dip" >

            <TextView
                android:id="@+id/tv_tab_1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1.0"
                android:gravity="center"
                android:text="@string/tab_1"
                android:textColor="@color/white"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/tv_tab_2"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1.0"
                android:gravity="center"
                android:text="@string/tab_2"
                android:textColor="@color/lightwhite"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/tv_tab_3"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1.0"
                android:gravity="center"
                android:text="@string/tab_3"
                android:textColor="@color/lightwhite"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/tv_tab_4"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1.0"
                android:gravity="center"
                android:text="@string/tab_4"
                android:textColor="@color/lightwhite"
                android:textSize="18sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:orientation="vertical"
            android:paddingBottom="3dip" >

            <ImageView
                android:id="@+id/iv_bottom_line"
                android:layout_width="40dip"
                android:layout_height="2dip"
                android:layout_marginLeft="20dip"
                android:scaleType="matrix"
                android:src="#fff" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

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

接下来是 MainActivity.java

package com.vatty.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * 
 * MainActivity.java
 * @author mayi
 * 2014-8-2 下午11:51:28
 *
 */
public class MainActivity extends FragmentActivity {
    private static final String TAG = "MainActivity";
    private ViewPager mPager;
    private ArrayList<Fragment> fragmentsList;
    private ImageView ivBottomLine;
    private TextView tv_tab_1, tv_tab_2, tv_tab_3, tv_tab_4;

    private int currIndex = 0;
    private int bottomLineWidth;
    private int offset = 0;
    private int position_one;
    private int position_two;
    private int position_three;
    private Resources resources;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        setContentView(R.layout.main);
        
        resources = getResources();
       
        InitWidth();
        
        InitTextView();
        
        InitViewPager();
    }
    
    /**
     * 获取底栏中的控件并添加监听事件
     */
    private void InitTextView() {
        tv_tab_1 = (TextView) findViewById(R.id.tv_tab_1);
        tv_tab_2 = (TextView) findViewById(R.id.tv_tab_2);
        tv_tab_3 = (TextView) findViewById(R.id.tv_tab_3);
        tv_tab_4 = (TextView) findViewById(R.id.tv_tab_4);

        tv_tab_1.setOnClickListener(new MyOnClickListener(0));
        tv_tab_2.setOnClickListener(new MyOnClickListener(1));
        tv_tab_3.setOnClickListener(new MyOnClickListener(2));
        tv_tab_4.setOnClickListener(new MyOnClickListener(3));
    }
    /**
     * 初始化ViewPager
     */
    private void InitViewPager() {
    	//获取布局中的viewpager控件
        mPager = (ViewPager) findViewById(R.id.vPager);
        //Fragment容器
        fragmentsList = new ArrayList<Fragment>();
         
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("userid","小洪");
        paramMap.put("age",23);
        
        
        Map<String, Object> paramMap2 = new HashMap<String, Object>();
        paramMap2.put("userid","vatty");
        paramMap2.put("age",24);
        
        Map<String, Object> paramMap3 = new HashMap<String, Object>();
        paramMap3.put("userid","小明");
        paramMap3.put("age",25);
        
        
        Map<String, Object> paramMap4 = new HashMap<String, Object>();
        paramMap4.put("userid","hongshengpeng.com");
        paramMap4.put("age",26);
       
        //生成每个tab对应的fragment
        Fragment activityfragment = TestFragment.newInstance("Hello Activity.",paramMap);
        Fragment groupFragment = TestFragment.newInstance("Hello Group.",paramMap2);
        Fragment friendsFragment=TestFragment.newInstance("Hello Friends.",paramMap3);
        Fragment chatFragment=TestFragment.newInstance("Hello Chat.",paramMap4);
        //添加到Fragment容器中
        fragmentsList.add(activityfragment);
        fragmentsList.add(groupFragment);
        fragmentsList.add(friendsFragment);
        fragmentsList.add(chatFragment);
        //给ViewPager添加适配器
        mPager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager(), fragmentsList));
        //设置默认的视图为第0个
        mPager.setCurrentItem(0);
        //给Viewpager添加监听事件
        mPager.setOnPageChangeListener(new MyOnPageChangeListener());
    }
    
    /**
     *  初始化底栏,获取相应宽度信息
     */
    private void InitWidth() {
        ivBottomLine = (ImageView) findViewById(R.id.iv_bottom_line);
        //获取底栏白色滑动线的宽度
        bottomLineWidth = ivBottomLine.getLayoutParams().width;
        Log.d(TAG, "cursor imageview width=" + bottomLineWidth);
        
        //获取屏幕宽度
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenW = dm.widthPixels;
        //屏幕分4份,计算出每份中白色滑条外的间隔距离
        offset = (int) ((screenW / 4.0 - bottomLineWidth) / 2);
        Log.i("MainActivity", "offset=" + offset);
        
        //计算出底栏的位置
        position_one = (int) (screenW / 4.0);
        position_two = position_one * 2;
        position_three = position_one * 3;
    }
    
    
    /**
     * 自定义监听类   如此定义监听类,可以实现共用。
     * @author Administrator
     *
     */
    public class MyOnClickListener implements View.OnClickListener {
        private int index = 0;

        public MyOnClickListener(int i) {
            index = i;
        }

        @Override
        public void onClick(View v) {
        	//设置ViewPager的当前view
            mPager.setCurrentItem(index);
        }
    };
    
    /**
     * 页面滑动监听
     * @author Administrator
     *
     */
    public class MyOnPageChangeListener implements OnPageChangeListener {

        @Override
        public void onPageSelected(int index) {
        	//动画
            Animation animation = null;
            switch (index) {
            case 0:
                if (currIndex == 1) {
                	//代码生成滑动动画
                	animation = new TranslateAnimation(position_one, 0, 0, 0);
                	//改变tv_tab_2的颜色值,使其没有选中的效果
                    tv_tab_2.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 2) {
                    animation = new TranslateAnimation(position_two, 0, 0, 0);
                    tv_tab_3.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 3) {
                    animation = new TranslateAnimation(position_three, 0, 0, 0);
                    tv_tab_4.setTextColor(resources.getColor(R.color.lightwhite));
                }
                //改变tv_tab_1的颜色值,使其有选中的效果
                tv_tab_1.setTextColor(resources.getColor(R.color.white));
                break;
            case 1:
                if (currIndex == 0) {
                    animation = new TranslateAnimation(0, position_one, 0, 0);
                    tv_tab_1.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 2) {
                    animation = new TranslateAnimation(position_two, position_one, 0, 0);
                    tv_tab_3.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 3) {
                    animation = new TranslateAnimation(position_three, position_one, 0, 0);
                    tv_tab_4.setTextColor(resources.getColor(R.color.lightwhite));
                }
                tv_tab_2.setTextColor(resources.getColor(R.color.white));
                break;
            case 2:
                if (currIndex == 0) {
                    animation = new TranslateAnimation(0, position_two, 0, 0);
                    tv_tab_1.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 1) {
                    animation = new TranslateAnimation(position_one, position_two, 0, 0);
                    tv_tab_2.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 3) {
                    animation = new TranslateAnimation(position_three, position_two, 0, 0);
                    tv_tab_4.setTextColor(resources.getColor(R.color.lightwhite));
                }
                tv_tab_3.setTextColor(resources.getColor(R.color.white));
                break;
            case 3:
                if (currIndex == 0) {
                    animation = new TranslateAnimation(0, position_three, 0, 0);
                    tv_tab_1.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 1) {
                    animation = new TranslateAnimation(position_one, position_three, 0, 0);
                    tv_tab_2.setTextColor(resources.getColor(R.color.lightwhite));
                } else if (currIndex == 2) {
                    animation = new TranslateAnimation(position_two, position_three, 0, 0);
                    tv_tab_3.setTextColor(resources.getColor(R.color.lightwhite));
                }
                tv_tab_4.setTextColor(resources.getColor(R.color.white));
                break;
            }
            //记录当前的页面位置
            currIndex = index;
            //动画播放完后,保持结束时的状态
            animation.setFillAfter(true);
            //动画持续时间
            animation.setDuration(300);
            //底栏滑动白线开始动画
            ivBottomLine.startAnimation(animation);
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
        
        }
    }
}

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

接下来就是Fragment模块:

TestFragment.java

package com.vatty.activity;

import java.util.ArrayList;
import java.util.Map;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import com.vatty.adapter.ContactAdapter;
import com.vatty.model.Contact;

/**
 * 
 * TestFragment.java
 * @author mayi
 * 2014-8-2 下午11:54:19
 *
 */
public class TestFragment extends Fragment {
	private static final String TAG = "TestFragment";
	private Map<String, Object> maplist;

	/**
	 * 获取新的Fragment
	 * @param s
	 * @param map
	 * @return
	 */
	static TestFragment newInstance(String s, Map<String, Object> map) {
		TestFragment newFragment = new TestFragment();
		final SerializableMap myMap = new SerializableMap();
		myMap.setMap(map);
		//Bundle 存储数据
		Bundle bundle = new Bundle();
		bundle.putSerializable("map", myMap);
		//Fragment传送数据
		newFragment.setArguments(bundle);
		return newFragment;

	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
//		Log.d(TAG, "TestFragment-----onCreate");
		//获取Fragment传送的数据
		Bundle bundle = getArguments();
		SerializableMap serializableMap = (SerializableMap) bundle.get("map");
		
		maplist = serializableMap.getMap();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
//		Log.d(TAG, "TestFragment-----onCreateView");
		
		//加载要在此Fragment中显示的layout(布局文件)
		View view = inflater.inflate(R.layout.lay1, container, false);
		
		//-------------------------------以下的根据自己项目的需要做开发----------------------------------------------
		//获取layout中的控件
		ListView lv = (ListView) view.findViewById(R.id.listView3);
		
		//getActivity().getApplicationContext()方法  获取Context
		ContactAdapter hc = new ContactAdapter(getActivity().getApplicationContext(), getContact());
		lv.setAdapter(hc);
		lv.setCacheColorHint(0);

		return view;

	}
	
	private ArrayList<Contact> getContact() {
		ArrayList<Contact> hcList = new ArrayList<Contact>();

		for (int i = 0; i < 10; i++) {
			Contact c0 = new Contact();
			c0.setTxPath(R.drawable.more_game + "");

			c0.setName(maplist.get("userid") + "  年龄:" + maplist.get("age"));
			hcList.add(c0);
		}

		return hcList;
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
//		Log.d(TAG, "TestFragment-----onDestroy");
	}

}

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

DEMO下载

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值