这一篇将讲述如何构建主页面,先看一下微信主页面的截图
从截图中可以看出,它的菜单是在程序的底部,当我们选择一个按钮后,它的颜色会发生变化,好像有灯在亮,这个实现起来比较简单,可以有多种方式供我们选择,TabActivity或者tabwidget+radiobutton或者activitygroup+radiobutton或者activitygroup+gridview或者activitygroup+grally等都可以,按钮的变化可以使用selector用两张图片来控制。
关于activitygroup,大家可以看一下这个图片:
先以tabwidget为例,代码如下:
import android.app.TabActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.Window; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TabHost; import android.widget.TextView; public class MainActivity extends TabActivity { /** Called when the activity is first created. */ private TabHost tabHost; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); tabHost=this.getTabHost(); TabHost.TabSpec spec; Intent intent; intent=new Intent().setClass(this, AddExamActivity.class); spec=tabHost.newTabSpec("微信").setIndicator("微信").setContent(intent); tabHost.addTab(spec); intent=new Intent().setClass(this,MyExamActivity.class); spec=tabHost.newTabSpec("通讯录").setIndicator("通讯录").setContent(intent); tabHost.addTab(spec); intent=new Intent().setClass(this, MyMessageActivity.class); spec=tabHost.newTabSpec("朋友们").setIndicator("朋友们").setContent(intent); tabHost.addTab(spec); intent=new Intent().setClass(this, Activity.class); spec=tabHost.newTabSpec("设置").setIndicator("设置").setContent(intent); tabHost.addTab(spec); intent=new Intent().setClass(this, SettingActivity.class); spec=tabHost.newTabSpec("设置").setIndicator("设置").setContent(intent); tabHost.addTab(spec); tabHost.setCurrentTab(1); } }xml布局文件如下:
<?xml version="1.0" encoding="utf-8"?> <TabHost android:id="@android:id/tabhost" //id必须为:tabhost android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:id="@android:id/tabcontent" //id必须为:tabcontent android:layout_width="fill_parent" android:layout_height="0.0dip" android:layout_weight="1.0" /> <TabWidget android:id="@android:id/tabs" //id必须为:tabs android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.0" /> </LinearLayout> 这些id都是系统的,只有这样,系统才会找到他们正确辨认。 </TabHost>再就是点击button的切换效果了,这里需要使用selector来实现,如下:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true" android:state_checked="true" android:drawable="@drawable/tab_weixin_pressed" />//点击后的绿色效果 <item android:drawable="@drawable/tab_weixin_normal" />//未点击的正常效果 </selector>这样就利用tabwidget实现了最基础的菜单布局,但是相信很多人都知道,使用tabwidget需要消耗比较大的内存,后来就有人使用activitygroup和其他的组件结合使用,如上举例。这里就不再介绍了,感兴趣的朋友可以去查阅资料。下面我们使用另外一个方法,这种方法相对来说更加优雅。为什么这么说,因为viewpager这个类相信大家都不陌生了,其实官方微信是不支持滑动页面的,但是利用viewpager这个类,我们也可以既可以点击又可以滑动的切换页面。而且我们也不使用selector来实现button的改变,而是利用一个动画来实现,这个工程就是绿色图片来覆盖各个button,呈现出一个绿色的效果。底部菜单也不是使用耗费资源的tabwidget而是利用布局来自定义的,xml文件如下,一眼就可以明白:
<?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 //viewpager类,用来切换页面 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>如图:
所以,主页面的代码主要是这样的,一方面要使用viewpager来实现滑动页面,另一方面要实现自定义菜单改变颜色的动画效果。代码如下:
import java.util.ArrayList; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.Display; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupWindow; public class MainWeixin extends Activity { public static MainWeixin instance = null; private ViewPager mTabPager;//声明对象 private ImageView mTabImg;// 动画图片 private ImageView mTab1, mTab2, mTab3, mTab4; private int zero = 0;// 动画图片偏移量 private int currIndex = 0;// 当前页卡编号 private int one;// 单个水平动画位移 private int two; private int three; private LinearLayout mClose; private LinearLayout mCloseBtn; private View layout; private boolean menu_display = false; private PopupWindow menuWindow; private LayoutInflater inflater; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_weixin); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);// 启动activity时不自动弹出软键盘 instance = this; mTabPager = (ViewPager) findViewById(R.id.tabpager); mTabPager.setOnPageChangeListener(new MyOnPageChangeListener()); 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)); Display currDisplay = getWindowManager().getDefaultDisplay();// 获取屏幕当前分辨率 int displayWidth = currDisplay.getWidth(); one = displayWidth / 4; // 设置水平动画平移大小 two = one * 2; three = one * 3; // 将要分页显示的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); } /** * 头标点击监听 */ public class MyOnClickListener implements View.OnClickListener { private int index = 0; public MyOnClickListener(int i) { index = i; } public void onClick(View v) { mTabPager.setCurrentItem(index); } }; /* * 页卡切换监听(原作者:D.Winter) */ public class MyOnPageChangeListener implements OnPageChangeListener { 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);// 开始动画 } }效果如下:
这样关于主页面的实现就完成了,之后会详细说一下各个Activity的实现。欢迎大家关注!