Android 仿土巴兔選擇效果


1,前兩天在群里看到有人在討論土巴兔的選擇裝修風格的效果,自己也想實現,果斷百度一下,有些好的文章,就花了些時間來分析了下,先看看別人土巴兔原裝的功能

2,可以看到,基本上可以使用一個vviewpager來實現,主要技術點一下

  ①android:clipChildren設置為false,意味着不限制子View在其范圍內,也就是說子view可以超出父view的范圍

  ②通過PageTransformer來實現縮放動畫

  ③攔截點擊事件的位置來實現點擊切換viewpager

來看一下代碼,首先看一下布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                xmlns:tools="http://schemas.android.com/tools"
                android:id="@+id/page_container"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white"
                android:clipChildren="false"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"
                tools:context=".MainActivity"
                tools:showIn="@layout/activity_main">

    <com.wangjitao.tubatudemo.view.ClipViewPager
        android:id="@+id/viewPager"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:clipChildren="false"
        android:overScrollMode="never" />

</RelativeLayout>

 其中ClipViewPager是一個自定義的viewpager,主要實現了兩個功能,一,判斷用戶點擊事件在不在Viewpager中,二,若在,則設置當前頁為其

   ClipViewPager.java

package com.wangjitao.tubatudemo.view;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by wangjitao on 2016/4/15.
 */
public class ClipViewPager extends ViewPager{
    public ClipViewPager(Context context) {
        super(context);
    }

    public ClipViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 重寫點擊事件,當用戶抬起的時候 判斷用戶點擊的區域是否在viewPager的區域中
     * 如果是,在判斷是在哪個子view上,然后設置當前頁為該view
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_UP){
            View view = viewOfClickOnScreen(ev);
            if (view != null){
                setCurrentItem(indexOfChild(view));
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    private View viewOfClickOnScreen(MotionEvent ev) {
        int childCount = getChildCount();
        int[] location = new int[2];
        for (int i = 0; i < childCount; i++) {
            View v = getChildAt(i);
            v.getLocationOnScreen(location);
            int minX = location[0];
            int minY = getTop();

            int maxX = location[0] + v.getWidth();
            int maxY = getBottom();

            float x = ev.getX();
            float y = ev.getY();

            if ((x > minX && x < maxX) && (y > minY && y < maxY)) {
                return v;
            }
        }
        return null;
    }
}

三,編寫自定義的PageTransformer ,來實現當前頁切換下一頁的控件的縮放問題

ScalePageTransformer.java
package com.wangjitao.tubatudemo.view;

import android.os.Build;
import android.support.v4.view.ViewPager;
import android.view.View;

/**
 * Created by wangjitao on 2016/4/15.
 */
public class ScalePageTransformer implements ViewPager.PageTransformer {

    public static final float MAX_SCALE = 1.2f ;
    public static final float MIN_SCALE = 0.6f ;

    /**
     * 當處於最中間的view往左邊滑動時,它的position值是小於0的,並且是越來越小,它右邊的view的position是從1逐漸減小到0的。
     * @param page
     * @param position
     */
    @Override
    public void transformPage(View page, float position) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            page.getParent().requestLayout();
        }
        if (position < -1) {
            position = -1;
        } else if (position > 1) {
            position = 1;
        }

        float tempScale = position < 0 ? 1 + position : 1 - position;

        float slope = (MAX_SCALE - MIN_SCALE) / 1;
        float scaleValue = MIN_SCALE + tempScale * slope;
        page.setScaleX(scaleValue);
        page.setScaleY(scaleValue);
    }
}

 基本上就可以實現了,再貼一下是MainActivity.java和ViewPager的Adapter

 MainActivity.java

package com.wangjitao.tubatudemo;

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RelativeLayout;

import com.wangjitao.tubatudemo.adapter.ClipPagerAdapter;
import com.wangjitao.tubatudemo.view.ClipViewPager;
import com.wangjitao.tubatudemo.view.ScalePageTransformer;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private Context mContext = MainActivity.this ;
    private ClipViewPager mViewPager ;
    private ClipPagerAdapter mClipViewPager ;
    private List<Integer> mData ;
    private RelativeLayout mRelativeLayout ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Hi Girl", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        initView();
        initData();
    }

    private void initView() {
        mViewPager = (ClipViewPager) findViewById(R.id.viewPager) ;

        mViewPager.setPageTransformer(true, new ScalePageTransformer());
        mRelativeLayout = (RelativeLayout) findViewById(R.id.page_container);

        //需要將整個頁面的事件分發給ViewPager,不然的話只有ViewPager中間的view能滑動,其他的都不能滑動,這是肯定的,
        //因為ViewPager總體布局就是中間那一塊大小,其他的子布局都跑到ViewPager外面來了
        mRelativeLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mViewPager.dispatchTouchEvent(event);
            }
        });

        mData = new ArrayList<>();
        mClipViewPager = new ClipPagerAdapter(mData,mContext);
        mViewPager.setAdapter(mClipViewPager);
    }

    private void initData() {
        mData.add(R.mipmap.style_xiandai);
        mData.add(R.mipmap.style_jianyue);
        mData.add(R.mipmap.style_oushi);
        mData.add(R.mipmap.style_zhongshi);
        mData.add(R.mipmap.style_meishi);
        mData.add(R.mipmap.style_dzh);
        mData.add(R.mipmap.style_dny);
        mData.add(R.mipmap.style_rishi);

        mViewPager.setOffscreenPageLimit(mData.size());
        mClipViewPager.notifyDataSetChanged();
    }


}

  ViewPager的適配器 ClipPagerAdapter.java

package com.wangjitao.tubatudemo.adapter;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.List;

/**
 * Created by jh on 2016/4/15.
 */
public class ClipPagerAdapter extends RecyclingPagerAdapter {
    private List<Integer> mData ;
    private Context mContext ;

    public ClipPagerAdapter(List<Integer> mData ,Context mContext ) {
        this.mData = mData ;
        this.mContext = mContext ;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup container) {
        ImageView imageView = null ;
        if (convertView == null){
            imageView = new ImageView(mContext);
        }else {
            imageView = (ImageView) convertView ;
        }
        imageView.setTag(position);
        imageView.setImageResource(mData.get(position));
        return imageView;
    }

    @Override
    public int getCount() {
        return mData.size();
    }
}

  ok ,基本上就完成了 ,看一看效果

    

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM