前面《 是男人就下100层【第一层】——高仿微信界面(4)》中我们已经完成了基本的引导界面和登录界面,这一篇中我们来看看登录后的主界面的布局和内容,来一步一步的完成该界面。
我们先来看看主界面如何布局,如下图所示,下部分的导航栏单独做成一个主布局,然后在上部分放入ViewPager组件,这个前面的引导界面有点类似。这种导航栏有多种实现方式,用TabHost也可以实现,用Fragement也可以实现,我们就用ViewPager先实现一下。
主布局界面布局文件如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainweixin" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="#eee" > <RelativeLayout android:id="@+id/main_bottom" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:orientation="vertical" android:background="@drawable/bottom_bar" > <ImageView android:id="@+id/img_tab_now" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="matrix" android:layout_gravity="bottom" android:layout_alignParentBottom="true" android:src="@drawable/tab_bg" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:paddingBottom="2dp" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" android:layout_weight="1"> <ImageView android:id="@+id/img_weixin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="matrix" android:clickable="true" android:src="@drawable/tab_weixin_pressed" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="微信" android:textColor="#fff" android:textSize="12sp" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" android:layout_weight="1"> <ImageView android:id="@+id/img_address" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="matrix" android:clickable="true" android:src="@drawable/tab_address_normal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="通讯录" android:textColor="#fff" android:textSize="12sp" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" android:layout_weight="1"> <ImageView android:id="@+id/img_friends" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="matrix" android:clickable="true" android:src="@drawable/tab_find_frd_normal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="朋友们" android:textColor="#fff" android:textSize="12sp" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" android:layout_weight="1"> <ImageView android:id="@+id/img_settings" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="matrix" android:clickable="true" android:src="@drawable/tab_settings_normal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="设置" android:textColor="#fff" android:textSize="12sp" /> </LinearLayout> </LinearLayout> </RelativeLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_above="@id/main_bottom" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/tabpager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" > </android.support.v4.view.ViewPager> </LinearLayout> </RelativeLayout>最外面我们使用了一个相对布局,其实线性布局也可以,任何界面都可以用多种方式来实现,有时候我们要考虑到性能的优化就需要合理的选择所需的实现方式。
相对布局中最下面是一个线性布局,在该布局中我们又放置了四个线性布局,每个线性布局就是下面导航菜单中的一个菜单项。相对布局的最上面是一个线性布局中放置了一个ViewPage组件,这样的设计完全符合上面我们所画的结构。
然后在Activity中我们将四个菜单所对应的布局文件通过加载器Inflate载入到View对象中并存入数组然后通过PageAdapter适配器填充界面。
// 将要分页显示的View装入数组中 LayoutInflater mLi = LayoutInflater.from(this); View view1 = mLi.inflate(R.layout.main_tab_weixin, null); View view2 = mLi.inflate(R.layout.main_tab_address, null); View view3 = mLi.inflate(R.layout.main_tab_friends, null); View view4 = mLi.inflate(R.layout.main_tab_settings, null); // 每个页面的view数据 final ArrayList<View> views = new ArrayList<View>(); views.add(view1); views.add(view2); views.add(view3); views.add(view4); // 填充ViewPager的数据适配器 PagerAdapter mPagerAdapter = new PagerAdapter() { @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getCount() { return views.size(); } @Override public void destroyItem(View container, int position, Object object) { ((ViewPager) container).removeView(views.get(position)); } // @Override // public CharSequence getPageTitle(int position) { // return titles.get(position); // } @Override public Object instantiateItem(View container, int position) { ((ViewPager) container).addView(views.get(position)); return views.get(position); } }; mTabPager.setAdapter(mPagerAdapter); }现在我们要做的就是通过四个菜单按钮的监听函数来切换ViewPager中的内容
mTab1 = (ImageView) findViewById(R.id.img_weixin); mTab2 = (ImageView) findViewById(R.id.img_address); mTab3 = (ImageView) findViewById(R.id.img_friends); mTab4 = (ImageView) findViewById(R.id.img_settings); mTabImg = (ImageView) findViewById(R.id.img_tab_now); mTab1.setOnClickListener(new MyOnClickListener(0)); mTab2.setOnClickListener(new MyOnClickListener(1)); mTab3.setOnClickListener(new MyOnClickListener(2)); mTab4.setOnClickListener(new MyOnClickListener(3));
/** * 头标点击监听 */ public class MyOnClickListener implements View.OnClickListener { private int index = 0; public MyOnClickListener(int i) { index = i; } @Override public void onClick(View v) { mTabPager.setCurrentItem(index); } };接下来还要解决一个问题,如何在选择菜单后,比如选择“通讯录”菜单后该菜单的背景颜色改变,有一种方法是将菜单中的ImageView换成CheckBox,或者用ViewPager的监听函数OnPageChangeListener来改变背景。
/* * 页卡切换监听(原作者:D.Winter) */ public class MyOnPageChangeListener implements OnPageChangeListener { @Override public void onPageSelected(int arg0) { Animation animation = null; switch (arg0) { case 0: mTab1.setImageDrawable(getResources().getDrawable( R.drawable.tab_weixin_pressed)); if (currIndex == 1) { animation = new TranslateAnimation(one, 0, 0, 0); mTab2.setImageDrawable(getResources().getDrawable( R.drawable.tab_address_normal)); } else if (currIndex == 2) { animation = new TranslateAnimation(two, 0, 0, 0); mTab3.setImageDrawable(getResources().getDrawable( R.drawable.tab_find_frd_normal)); } else if (currIndex == 3) { animation = new TranslateAnimation(three, 0, 0, 0); mTab4.setImageDrawable(getResources().getDrawable( R.drawable.tab_settings_normal)); } break; case 1: mTab2.setImageDrawable(getResources().getDrawable( R.drawable.tab_address_pressed)); if (currIndex == 0) { animation = new TranslateAnimation(zero, one, 0, 0); mTab1.setImageDrawable(getResources().getDrawable( R.drawable.tab_weixin_normal)); } else if (currIndex == 2) { animation = new TranslateAnimation(two, one, 0, 0); mTab3.setImageDrawable(getResources().getDrawable( R.drawable.tab_find_frd_normal)); } else if (currIndex == 3) { animation = new TranslateAnimation(three, one, 0, 0); mTab4.setImageDrawable(getResources().getDrawable( R.drawable.tab_settings_normal)); } break; case 2: mTab3.setImageDrawable(getResources().getDrawable( R.drawable.tab_find_frd_pressed)); if (currIndex == 0) { animation = new TranslateAnimation(zero, two, 0, 0); mTab1.setImageDrawable(getResources().getDrawable( R.drawable.tab_weixin_normal)); } else if (currIndex == 1) { animation = new TranslateAnimation(one, two, 0, 0); mTab2.setImageDrawable(getResources().getDrawable( R.drawable.tab_address_normal)); } else if (currIndex == 3) { animation = new TranslateAnimation(three, two, 0, 0); mTab4.setImageDrawable(getResources().getDrawable( R.drawable.tab_settings_normal)); } break; case 3: mTab4.setImageDrawable(getResources().getDrawable( R.drawable.tab_settings_pressed)); if (currIndex == 0) { animation = new TranslateAnimation(zero, three, 0, 0); mTab1.setImageDrawable(getResources().getDrawable( R.drawable.tab_weixin_normal)); } else if (currIndex == 1) { animation = new TranslateAnimation(one, three, 0, 0); mTab2.setImageDrawable(getResources().getDrawable( R.drawable.tab_address_normal)); } else if (currIndex == 2) { animation = new TranslateAnimation(two, three, 0, 0); mTab3.setImageDrawable(getResources().getDrawable( R.drawable.tab_find_frd_normal)); } break; } currIndex = arg0; animation.setFillAfter(true);// True:图片停在动画结束位置 animation.setDuration(150); mTabImg.startAnimation(animation); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }上面的currIndex是为了记住上次的状态,将上次的按钮背景还原。
布局效果如下:
效果是不是很酷?呵呵,如果有什么更好的实现方式或不对之处请大家拍砖,相互交流,共同进步。如果你喜欢阳光小强(大碗干拌)的博客,想共同学习,可以加入左边栏的交流群,该群中有来自全国各地的技术爱好者,欢迎~~
下一篇我们来详细看一下四个菜单所对应的界面实现,并贴出源代码。