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 ,基本上就完成了 ,看一看效果

  

 

Android 仿土巴兔选择效果的更多相关文章

  1. android仿iphone的地区选择

    最近项目要做一个,类似淘宝手机客户端的,选择收货地址的三级联动滚动选择组件,下面是它的大致界面截图: 在IOS中有个叫UIPickerView的选择器,并且在dataSource中定义了UIPicke ...

  2. Android 轻松实现仿淘宝地区选择

    介绍 最近用淘宝客户端的时候,编辑地址的时候有个地区选择的功能.看上面的效果觉得挺酷,滚动的时候,是最后一个从下面飞上来挨着前一个.就自己鼓捣一个出来玩玩. 说了效果可能不太直观,下面上两张图看看效果 ...

  3. 商城项目实战 | 1.1 Android 仿京东商城底部布局的选择效果 —— Selector 选择器的实现

    前言 本文为菜鸟窝作者刘婷的连载."商城项目实战"系列来聊聊仿"京东淘宝的购物商城"如何实现. 京东商城的底部布局的选择效果看上去很复杂,其实很简单,这主要是要 ...

  4. Android仿苹果版QQ下拉刷新实现(二) ——贝塞尔曲线开发"鼻涕"下拉粘连效果

    前言 接着上一期Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件 的博客开始,同样,在开始前我们先来看一下目标效果: 下面上一下本章需要实现的效果图: 大家看到这个效果 ...

  5. jquery仿淘宝规格颜色选择效果

    jquery实现的仿淘宝规格颜色选择效果源代码如下 jquery仿淘宝规格颜色选择效果 -收缩HTML代码 运行代码 [如果运行无效果,请自行将源代码保存为html文件运行] <script t ...

  6. 仿360手机卫士界面效果android版源码

    仿360手机卫士界面效果android版,这个今天一大早在源码天堂的那个网站上看到了一个那个网站最新更新的一个源码,所以就分享给大学习一下吧,布局还挺不错的,而且也很简单的,我就不把我修改的那个分享出 ...

  7. Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应

    版权声明:本文为博主原创文章,未经博主允许不得转载.  Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应  上一篇讲过了主体界面的绘制,这里讲解调色板应用中的另外一 ...

  8. Android仿IOS回弹效果 ScrollView回弹 总结

    Android仿IOS回弹效果  ScrollView回弹 总结 应项目中的需求  须要仿IOS 下拉回弹的效果 , 我在网上搜了非常多 大多数都是拿scrollview 改吧改吧 试了一些  发现总 ...

  9. Android实现下拉导航选择菜单效果

    本文介绍在Android中如何实现下拉导航选择菜单效果.   关于下拉导航选择菜单效果在新闻客户端中用的比较多,当然也可以用在其他的项目中,这样可以很方便的选择更多的菜单.我们可以让我们的应用顶部有左 ...

随机推荐

  1. HTML5的新事件

    HTML 元素可拥有事件属性,这些属性在浏览器中触发行为,比如当用户单击一个 HTML 元素时启动一段 JavaScript. HTML 元素可拥有事件属性,这些属性在浏览器中触发行为,比如当用户单击 ...

  2. python 输出乱码

    在Python中有两种默认的字符串:str和unicode.在Python中一定要注意区分“Unicode字符串”和“unicode对象”的区别.后面所有的“unicode字符串”指的都是python ...

  3. LTRIM(str):返回 字符串str的前导(左边)空格字符去掉。

    SELECT ' 11' res SELECT LTRIM(' 11') resL 运行结果:

  4. EF6 CodeFirst 启用Migration,常用命令

    Enable-Migrations –EnableAutomaticMigrationsAdd-Migration [MigrationName] [-Force]Update-Database –T ...

  5. android 直接启动其他应用的Service

    最近在做一个小插件,没有图标没有activity,利用其他APK启动它的service. 直奔主题,插件A,安装插件的应用B. B安装A后,由于A刚被安装,没有注册广播接收器,这里不考虑AIDL.需求 ...

  6. 面向对象分析方法(I)

    找出最关键的一些业务场景:一般通过动词来寻找,比如招聘系统中,一个应聘人投递一个职位就是一次应聘,应聘就是一个业务场景:一个学生参加某门课的考试,那么考试就是一个业务场景:一个学生去图书馆借书,那么借 ...

  7. java web filter 之一 基础实现

    本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...

  8. out 和 ref 之间的区别整理

    ref和out都是C#中的关键字,所实现的功能也差不多,都是指定一个参数按照引用传递. 对于编译后的程序而言,它们之间没有任何区别,也就是说它们只有语法区别. 总结起来,他们有如下语法区别: 1.re ...

  9. select下拉框美化

      其实用下列CSS就可以解决,原理是将浏览器默认的下拉框样式清除,然后应用上自己的,再附一张向右对齐小箭头的图片即可. select { /*Chrome和Firefox里面的边框是不一样的,所以复 ...

  10. 配置本地yum源

    配置本地yum源 一.  远程挂载ISO文件 mount /dev/sr0 /mnt/cdrom (本地挂载mount -t iso9660 -o loop xx.iso /media) 二.  配置 ...