ViewPager+gridView仿美团导航

     相信大家都用过美团吧,是不是被它的精美的导航页面给迷住!今天,咱们就实现它那个多页面滑动导航效果,话不多说,先上效果图:
                                                    
我是在模拟器上运行的结果,文字样式大小以及圆点颜色等,大家都可以自己设置,在真机上面效果应该会更好!该项目主要基于ViewPager和gridView的整合应用.项目源码链接如下, 点击下载

问题思考

(1)viewPager加载的View是什么,怎么把这些数据加载进去?
(2)小圆点是怎样设计的,它样式怎么控制?

     我们先看第一个问题,我这里ViewPager中添加的View直接就是gridView.关键代码如下:
private void initView() {
		int pageCount = (int) Math.ceil(titles.length
				* 1.0
				/ Integer.parseInt(this.getResources().getString(
						R.string.page_size)));
		for (int i = 0; i < pageCount; i++) {
			GridView gridView = (GridView) View.inflate(this,
					R.layout.gridview, null);
			RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
					-1, -1);
			gridView.setLayoutParams(lp);
			/*
			 * gridView.setAdapter(new SimplePagerAdapter(this,
			 * getDefaultData(), R.layout.item, new String[] { "imgId", "title"
			 * }, new int[] { R.id.imageView, R.id.tv }, i + 1));
			 */
			gridView.setAdapter(new SimplePagerAdapter2(this, getData(),
					R.layout.item, i + 1));
			viewList.add(gridView);
			View v = View.inflate(this, R.layout.dot, null);
			int d = this.getResources().getDimensionPixelOffset(
					R.dimen.dot_diameter);
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(d,
					d);
			params.leftMargin = this.getResources().getDimensionPixelOffset(
					R.dimen.dot_marginLeft);
			v.setLayoutParams(params);
			dotLayout.addView(v);
		}
		// 初始化第一个小圆点
		dotLayout.getChildAt(0).setBackgroundResource(R.drawable.dot_choose);
		viewPager.setAdapter(new BasePagerAdapter(viewList));
       可以看到,在这里,我先计算出有多少个页面(ceil(数据总数/每页显示数量)),在每页中,实例话一个gridView,并加入到viewList作为ViewPager的PagerAdapter,注意,这时我们就要提供页数来计算gridView加载的数据了,这个在simplePagerAdapter2(gridView适配器中)有体现。我们再看看SimplePagerAdapter2中关键代码如下:
	private Context context;
	private List<Map<integer object="">> data;
	private Integer mresourceId;
	private int currentPage;
	private int pageSize;
	private int pageCount;

	public SimplePagerAdapter2(Context context,
			List<Map<integer object="">> data, Integer mresourceId,
			int currentPage) {
		this.context = context;
		this.data = data;
		this.mresourceId = mresourceId;
		this.currentPage = currentPage;
		this.pageSize = Integer.parseInt(context.getResources().getString(
				R.string.page_size));
		pageCount = (int) Math.ceil(data.size() * 1.0 / this.pageSize);
	}
</integer></integer>
           这个是它的属性和构造方法,可以看到,我这里的传递的数据集合 data类型是List<Map>而不是List<Map>类型,并没有仿照SimpleAdapter写法.大家看如下赋值代码:
	private List<Map<integer object="">> getData() {
		List<Map<integer object="">> list = new ArrayList<Map<integer object="">>();
		for (int i = 0; i < Math.min(titles.length, imgId.length); i++) {
			Map<integer object=""> map = new HashMap<integer object="">();
			map.put(R.id.imageView, imgId[i]);
			map.put(R.id.tv, titles[i]);
			list.add(map);
		}
		return list;
	}
</integer></integer></integer></integer></integer>
             看到没,我的Map集合的里的Key是什么?是不是要解析的每项layout中的view的id!直接设成key后,可以简化参数传递,我在这也只是起到抛砖引玉的作用,大家可以下载代码体会,相信你肯定能想到体会.

             那么第二个问题是怎样解决呢?首先需要说明的是,每个原点就是一个view,我们看activity_main.xml代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ccc"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200dip"
        android:background="#fff" >

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </android.support.v4.view.ViewPager>

        <LinearLayout
            android:id="@+id/dotLayout"
            android:layout_width="match_parent"
            android:layout_height="12dip"
            android:layout_alignParentBottom="true"
            android:gravity="center"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>

        可以看到,在主布局文件中,只是添加了LinearLayout,小圆点肯定是放在这里面的,那么在java代码中我们是如何处理的呢?处理代码如下:
			View v = View.inflate(this, R.layout.dot, null);
			int d = this.getResources().getDimensionPixelOffset(
					R.dimen.dot_diameter);
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(d,
					d);
			params.leftMargin = this.getResources().getDimensionPixelOffset(
					R.dimen.dot_marginLeft);
			v.setLayoutParams(params);
			dotLayout.addView(v);
解析dot.xml文件读取view,然后设置view的布局参数,并添加到LinearLayout中,我们再来看看,dot.xml定义:
<view xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dotImg" android:background="@drawable/dot_default">
</view>
       可以看到,view只是简单的定义background属性,有的朋友可能要问了,为啥不把view的属性id定义放在dot.xml中,而是设置在上面的java代码中,比如说leftMargin属性。在这里需要说明的是,直接写效果肯定是出不来的,除非在view外面加个LinearLayout(RelativeLayout等布局),具体原因,可以参考我的另一篇文章: 代码中设置View的LayoutParams,里面又详细解释。然后再配合ViewPager的setOnPageChangeListener就可以实现小圆点的背景样式的切换了,代码如下:
 // 初始化第一个小圆点
		dotLayout.getChildAt(0).setBackgroundResource(R.drawable.dot_choose);
		viewPager.setAdapter(new BasePagerAdapter(viewList));
		viewPager.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int arg0) {
				MainActivity.this.resetDotBackground();
				dotLayout.getChildAt(arg0).setBackgroundResource(
						R.drawable.dot_choose);
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {
				// TODO Auto-generated method stub

			}
		});

     讨论到这,我们的这个仿美团导航效果就说完了。最后,欢迎大家和我一起学习讨论,一起提高!
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值