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的,就跟我们平常开发的没多大区别,大家可以去下载代码查看。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。