Viewpager (一)
Contents
主界面的知识点分析
根据上图分析可得有下列知识点
- 底部tab的实现
- Viewpager的实现
- PopupWindow的实现
底部tab的布局实现
分析可得:底部tag由一个LinearLayout主Layout组成、主Layout又由4个水平子LinearLayout子Layout组成,每个子layout包括一个ImageView、TextVie在主Layout下面还有一个移动标签,这是一个ImageView。最终外面是一个RelativeLayout囊括着主Layout跟移动标签ImageView。
布局代码如下
<RelativeLayout android:id="@+id/main_bottom" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:background="@drawable/bottom_bar" android:orientation="vertical"> //这是一个移动标签、用于表示当前选中的tag <ImageView android:id="@+id/img_tab_now" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_gravity="bottom" android:scaleType="matrix" 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:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <ImageView android:id="@+id/img_weixin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:scaleType="matrix" 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:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <ImageView android:id="@+id/img_address" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:scaleType="matrix" 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:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <ImageView android:id="@+id/img_friends" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:scaleType="matrix" 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:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <ImageView android:id="@+id/img_settings" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:scaleType="matrix" 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>
ViewPager的布局实现
导入v4包,使用原生的ViewPager,使其布局在底部tag上方
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_above="@id/main_bottom" android:layout_alignParentTop="true" 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>
这样选项卡切换的布局就做好了。
接下来,我们要做的就是将tab跟Viewpager 联系起来。首先我们先实现ViewPager自身的滑动切换,然后再实现点击切换。
ViewPager切换的实现
ViewPager显示的是不同的布局文件,所以我们可以通过将这些布局文件转换成View对象,然后传递给ViewPager的Adapter。这样就可以实现切换了。
4个布局文件分别是Wechat、Contact、Friends、Setting,我们可以通过LayoutInflater方法来将其转成View对象。
代码如下:
LayoutInflater inflate = getLayoutInflater(); View wechat = inflate.inflate(R.layout.activity_wechat,null); View contact = inflate.inflate(R.layout.activity_contact,null); View friends = inflate.inflate(R.layout.activity_friends,null); View setting = inflate.inflate(R.layout.activity_setting,null); //创建一个List 用于储存上面的View对象 ArrayList<View> views = new ArrayList<View>(); views.add(wechat); views.add(contact); views.add(friends); view.add(setting); //创建ViewPager的Adapter,重写其四大方法 PagerAdapter pagerAdapter = new PagerAdapter() { @Override public boolean isViewFromObject(View arg0, Object arg1) { // TODO Auto-generated method stub return arg0 == arg1; } @Override public int getCount() { //返回要滑动的VIew的个数 即上述集合views的长度 return viewList.size(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { // 从当前container中删除指定位置(position)的View; container.removeView(viewList.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { // 将当前视图添加到container中, 返回当前View container.addView(viewList.get(position)); return viewList.get(position); } }; viewPager.setAdapter(pagerAdapter); }
上述重写的代码中,我们将四大方法里的View参数改成了ViewGroup,否则我们需要进行强转。默认View是没有addView()这个方法的。所以我们需要通过ViewGroup来添加View。
接下来,我们要实现的是
1. 滑动改变底部tag图标的颜色。
2. 点击底部图标跳到相应的tag。
3. 下划线指示当前tag(imageview跟随着tag移动)。
- 通过viewpager的onPageChangeListener监听器 的onPageSelected()方法根据当前选项卡的坐标,可以设定相应的图片。**(最后要保存当前的坐标)**
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:
//同理上述
break;
case 2:
break;
case 3:
break;
}
//记录当前的坐标
currIndex = arg0;
animation.setFillAfter(true);// True:图片停在动画结束位置
animation.setDuration(150); // 设置动画时间
mTabImg.startAnimation(animation);
}
- 为四个图标设定相应的点击事件,并且传入左边给其构造函数,然后通过viewpager的setCurrentItem方法来跳到相应的tag。
代码如下:
//mTab1 是一个imageView
mTab1.setOnClickListener(new ErinListener(0));
mTab2.setOnClickListener(new ErinListener(1));
mTab3.setOnClickListener(new ErinListener(2));
mTab4.setOnClickListener(new ErinListener(3));
public class ErinListener implements View.OnClickListener {
private int index = 0;
public ErinListener(int i) {
index = i;
}
@Override
public void onClick(View v) {
viewPager.setCurrentItem(index);
}
};
- 下划线移动需要通过动画来实现,重写onPageChanged方法
分析:
我们需要获取屏幕的宽度,然后得到平均宽度。 (借助Display类) 通过动画在屏幕的4个部分中切换。
Display display = getWindowManager().getDefaultDisplay();
int width = display/4;
int zero = 0;
int one = width;
int two = width*2;
int three = width*3;
其余代码重写如上述
利用平移动画TranslateAnimation