1、概述
最近有不少朋友私聊问应用宝、360软件助手之类的软件详情页怎么做,刚好,最近有时间就模仿360软件助手详情页给大家做个Demo,供大家参考。嗯,关于实现呢,我写了两种方式:
1、ScrollView内嵌软件介绍+ViewPager+ViewPager中是ScrollView,这种方式呢,纯原生,没有涉及到自定义控件,但是这样嵌套呢,涉及到测量以及事件的冲突处理,大家可以自己尝试去做一下,想像起来蛮容易的,做起来其实还是挺费劲的,代码我会给出,核心代码不多,大家自行参考。本文将重点分析第二种方式。
2、将做外层的ScrollView改为了自定义的一个控件,继承自LinearLayout,叫做StickyNavLayout,这里感谢小七的命名,同时本方式感谢二群暖暖提供的源码。
最后看下效果图,第一张是360的,第二张是我们的:
360:
擦,别问我为什么这么模糊,尽力了。。。
我们的效果图:
2、使用方式
上面我们也说了,之所以有第二种方式,完全是为了考虑使用的容易度。
1、自定义id资源文件
values/ids_sticky_nav_Llayout.xml.
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <resources> <item name="id_stickynavlayout_topview" type="id"/> <item name="id_stickynavlayout_viewpager" type="id"/> <item name="id_stickynavlayout_indicator" type="id"/> <item name="id_stickynavlayout_innerscrollview" type="id"/> </resources> |
定义了几个id资源,主要是为了方便使用了,供声明布局时使用的,看名字应该能猜出来吧,猜不出来没事,接下来我就贴布局文件了。这个其实不属于使用方式了,但是下文会见到,所以提前贴出来。
2、布局文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<com.zhy.view.StickyNavLayout xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:id="@id/id_stickynavlayout_topview" android:layout_width="match_parent" android:layout_height="300dp" android:background="#4400ff00" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="软件介绍" android:textSize="30sp" android:textStyle="bold" /> </RelativeLayout> <com.zhy.view.SimpleViewPagerIndicator android:id="@id/id_stickynavlayout_indicator" android:layout_width="match_parent" android:layout_height="50dp" android:background="#ffffffff" > </com.zhy.view.SimpleViewPagerIndicator> <android.support.v4.view.ViewPager android:id="@id/id_stickynavlayout_viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#44ff0000" > </android.support.v4.view.ViewPager> </com.zhy.view.StickyNavLayout> |
最外层是我们的自定义的控件StickyNavLayout,然后是顶部内容区域,Vp的指示器,ViewPager。按照效果图,去写就ok,注意部分id使用我们预设定的id资源。因为我们的StickyNavLayout需要通过id找到该控件,去进行一些计算。
然后在我们的MainActivity中,对ViewPager进行初始化即可。
3、MainActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
package com.zhy.sample.StickyNavLayout; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import com.zhy.view.SimpleViewPagerIndicator; public class MainActivity extends FragmentActivity { private String[] mTitles = new String[] { "简介", "评价", "相关" }; private SimpleViewPagerIndicator mIndicator; private ViewPager mViewPager; private FragmentPagerAdapter mAdapter; private TabFragment[] mFragments = new TabFragment[mTitles.length]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); initDatas(); initEvents(); } private void initEvents() { mViewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { mIndicator.scroll(position, positionOffset); } @Override public void onPageScrollStateChanged(int state) { } }); } private void initDatas() { mIndicator.setTitles(mTitles); for (int i = 0; i < mTitles.length; i++) { mFragments[i] = (TabFragment) TabFragment.newInstance(mTitles[i]); } mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public int getCount() { return mTitles.length; } @Override public Fragment getItem(int position) { return mFragments[position]; } }; mViewPager.setAdapter(mAdapter); mViewPager.setCurrentItem(0); } private void initViews() { mIndicator = (SimpleViewPagerIndicator) findViewById(R.id.id_stickynavlayout_indicator); mViewPager = (ViewPager) findViewById(R.id.id_stickynavlayout_viewpager); } } |
没有什么复杂的代码,主要就是初始化我们的Vp;
对了这个指示器我是临时写的,也算一个自定义控件吧,主要就是跟随Vp一起移动,详细写法请参考:Android 教你打造炫酷的ViewPagerIndicator 不仅仅是高仿MIUI,只是把三角形改成了下划线,非本文重点,你可以暂时忽略。
我们的Vp中每个页面为一个Fragment,Fragment的代码我们就不贴了,布局就是ScrollView为根布局,内部随意填充,具体可参考源码。
介绍完了用法有木有一点小激动,基本按照常规去写布局就ok,效果自动实现。
4、Fragment及其布局
贴一下我们的Fragment代码: