相信大家都用过美团吧,是不是被它的精美的导航页面给迷住!今天,咱们就实现它那个多页面滑动导航效果,话不多说,先上效果图:
我是在模拟器上运行的结果,文字样式大小以及圆点颜色等,大家都可以自己设置,在真机上面效果应该会更好!该项目主要基于ViewPager和gridView的整合应用.项目源码链接如下, 点击下载
(2)小圆点是怎样设计的,它样式怎么控制?
我们先看第一个问题,我这里ViewPager中添加的View直接就是gridView.关键代码如下:
![](https://img-my.csdn.net/uploads/201610/29/1477730672_2154.gif)
我是在模拟器上运行的结果,文字样式大小以及圆点颜色等,大家都可以自己设置,在真机上面效果应该会更好!该项目主要基于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
}
});
讨论到这,我们的这个仿美团导航效果就说完了。最后,欢迎大家和我一起学习讨论,一起提高!