ViewPager+gridView仿美团导航

来源:互联网 发布:淘宝做工瑕疵 编辑:程序博客网 时间:2024/06/08 05:49
     相信大家都用过美团吧,是不是被它的精美的导航页面给迷住!今天,咱们就实现它那个多页面滑动导航效果,话不多说,先上效果图:
                                                    
我是在模拟器上运行的结果,文字样式大小以及圆点颜色等,大家都可以自己设置,在真机上面效果应该会更好!该项目主要基于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() {@Overridepublic void onPageSelected(int arg0) {MainActivity.this.resetDotBackground();dotLayout.getChildAt(arg0).setBackgroundResource(R.drawable.dot_choose);}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stub}});

     讨论到这,我们的这个仿美团导航效果就说完了。最后,欢迎大家和我一起学习讨论,一起提高!
0 0
原创粉丝点击