Android 模仿搜狐新聞的ViewpagerIndicator

來源:互聯網
上載者:User

標籤:android   選項卡   viewpager跟隨滾動   

好久沒寫部落格了,今天沒事怒更一記。

如標題今天我們來模仿一下搜狐新聞,先上個.


上完之後再上個部落格,我也是從這裡得到的啟發http://blog.csdn.net/qibin0506/article/details/42046559


1,接下來我們就來分析一下這個效果

下面的內容應該是用viewpager,頭部的選項卡我們用一個LinearLayout+HorizontalScrollView也可以實現,滾動效果的話我們可以用到我們學會的scrollTo,大致的思路理清,我們就開始碼代碼吧!

2,自訂LinearLayout

我們可以觀察到那個紅色的矩形應該是和整體的LinearLayout在一起,所以我們可以自訂LinearLayout畫出那個矩形,滾動就是改變畫矩形的位置即可

<span style="font-size:14px;">public class ViewpagerIndicator extends LinearLayout {    /**     * 畫筆,底部矩形     */    private Paint paint;    /**     * 子View個數     */    private int mCount;    private int mTop;    private int mWidth;    private int mLeft;    private int mHeight = 5;    public OnTextClick onTextClick;    public ViewpagerIndicator(Context context) {        super(context);    }    public ViewpagerIndicator(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(Color.TRANSPARENT);        paint = new Paint();        paint.setColor(getResources().getColor(R.color.red));        paint.setAntiAlias(true);    }    public interface OnTextClick{       public void textViewClick(int position);    }    public void setOnTextClick(OnTextClick onTextClick){        this.onTextClick = onTextClick;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //整體高度        mTop = getMeasuredHeight();        //整體寬度        int width = getMeasuredWidth();        //加上指標高度        int height = mTop + mHeight;        //指標的寬度        mWidth = width / mCount;        setMeasuredDimension(width, height);    }</span>

在onMeasure中我們拿到我們想要的關於位置距離的值,接下來我們就可以在onDraw中畫出想要的矩形了

<span style="font-size:14px;">/**     * 畫出指標     * @param canvas     */    protected void onDraw(Canvas canvas) {        Rect rect = new Rect(mLeft, mTop, mLeft + mWidth, mTop + mHeight);        canvas.drawRect(rect, paint);    }</span>

沒錯,就是倆句代碼,之後通過不斷的改變left就可以實現跟隨滾動的效果。

<span style="font-size:14px;">  /**     * 滾動效果     * @param position     * @param positionOffset     */    public void scrollTo(int position, float positionOffset) {        mLeft = (int) ((position + positionOffset) * mWidth);        postInvalidate();    }</span>
方法中的倆個參數我們可以通過viewpager的回調方法onPageScrolled中得到,position就是當前的選項卡,positionOffset相當於滑動的百分比0.0~0.0之間.

3,使用自訂控制項

ok,大致的思路都已經理清,接下來我們就可以使用自己做的Indicator了。

<span style="font-size:14px;"><RelativeLayout 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"    tools:context="topnews.inhome.wrh.fragment.NewsFragment">    <HorizontalScrollView        android:id="@+id/horizon"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:scrollbars="none"        >        <com.wrh.sohunews.ViewpagerIndicator            android:id="@+id/indicator"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:paddingBottom="10dp"            android:paddingTop="10dp">            <TextView                android:layout_width="0dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:layout_margin="10dp"                android:text="首頁"                android:textColor="@color/red"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="訂閱"                android:layout_margin="10dp"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="娛樂"                android:layout_margin="10dp"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:layout_margin="10dp"                android:text="本地"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:layout_margin="10dp"                android:text="生活"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="軍事"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="財經"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="社會"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="汽車"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="體育"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="曆史"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="搞笑"                android:gravity="center" />            <TextView                android:layout_width="0dp"                android:layout_margin="10dp"                android:layout_height="fill_parent"                android:layout_weight="1"                android:text="情感"                android:gravity="center" />        </com.wrh.sohunews.ViewpagerIndicator>    </HorizontalScrollView>    <android.support.v4.view.ViewPager        android:id="@+id/viewpager"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/horizon"        /></RelativeLayout></span>
先不要被眼前多如狗的TextView嚇到,其實都是粘貼複製上去的改了一個text就行,我們也可以在自己的LinearLayout中通過TextView t = new TextView();然後add進去,這倆種方法都可以。

但是我們顯然都不想給這麼多的textview都取id然後拿到它的執行個體再setOnClick,所以我們就可以在自訂的ViewGroup中直接set

 <span style="font-size:14px;">@Override    protected void onFinishInflate() {        super.onFinishInflate();        mCount = getChildCount();        /**         * 監聽點擊事件,回調介面         */        for (int i = 0 ;i<mCount;i++){            View view = getChildAt(i);            if (view instanceof TextView)            {                final int finalI = i;                ((TextView) view).setOnClickListener(new OnClickListener() {                    @Override                    public void onClick(View v) {                         if (onTextClick != null) {                             onTextClick.textViewClick(finalI);                         }                    }                });            }        }    }</span>
通過回調介面我們就輕易的拿到了所點擊的是哪一頁選項卡,接下來我們來看看使用方法

<span style="font-size:14px;">public class MainActivity extends Activity implements ViewPager.OnPageChangeListener,ViewpagerIndicator.OnTextClick{    private ViewPager viewPager;    private int lastX = 0;    private ViewpagerIndicator indicator;    private HorizontalScrollView horizontalScrollView;    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initViews();    }    private void initViews() {        viewPager = (ViewPager) findViewById(R.id.viewpager);        indicator = (ViewpagerIndicator) findViewById(R.id.indicator);        indicator.setOnTextClick(this);        horizontalScrollView = (HorizontalScrollView) findViewById(R.id.horizon);        viewPager.setAdapter(new MyAdapter());        viewPager.setOnPageChangeListener(this);    }</span>
一些必要的執行個體化.

<span style="font-size:14px;">  /**     * 只有當從第一項滾動第二項或者從第二項滾動第一項時,整體不動指標單獨滾動,其餘都是整個布局滾動     * @param position     * @param positionOffset     * @param positionOffsetPixels     */    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        if (!(position == 0 && positionOffset - lastX >= 0) || !(position == 1 && positionOffset - lastX <= 0)){            horizontalScrollView.scrollTo((int)((positionOffset+position-1)*indicator.getIndicatorWidth()), 0);        }        indicator.scrollTo(position, positionOffset);        lastX = (int) positionOffset;    }    @Override    public void onPageSelected(int position) {        indicator.resetTextViewColor();         indicator.setFocusTextView(position);    }    @Override    public void onPageScrollStateChanged(int state) {    }</span>
通過觀察搜狐新聞我們可以看到,當從第一頁滑動到第二頁時,只有Indicator滾動了,之後都是整體滾動,所以我們要做好判斷,整體滾動的時候indicator就相當於停留在了顯示出來的第二個選項卡,接下來我們看看實際效果.



效果還是闊以的嘛,哢哢。


項目源碼


Android 模仿搜狐新聞的ViewpagerIndicator

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.