zoukankan      html  css  js  c++  java
  • 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 ,基本上就完成了 ,看一看效果

        

      

     

  • 相关阅读:
    深拷贝与浅拷贝+可变与不可变的数据类型
    列表+列表循环+列表切片+元祖
    接口+session与cookie的区别+http状态码
    JSP中文乱码问题终极解决方案
    关于AS使用git的那些奇葩事儿
    ListView中动态显示隐藏HeaderView和FooterView
    关于沉浸式的那些奇葩问题
    Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析
    快速搭建tab
    使用 gradle 在编译时动态设置 Android resValue / BuildConfig / Manifes中<meta-data>变量的值
  • 原文地址:https://www.cnblogs.com/wjtaigwh/p/5395250.html
Copyright © 2011-2022 走看看