1. 程式人生 > >Android之仿淘寶商品詳情瀏覽效果

Android之仿淘寶商品詳情瀏覽效果

-----------------轉載請註明出處:http://blog.csdn.net/android_cll

一:先來幾張效果圖,沒有弄gif動畫,也就是商品詳情滑動到底部繼續上滑檢視圖文詳情、




二:實現步驟:

  1.自定義一個父容器ScrollViewContainer裝載兩個ScrollView、

package com.zjtd.bzcommunity.util;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.widget.RelativeLayout; import android.widget.ScrollView; import java.util.Timer; import java.util.TimerTask; /** * 包含兩個ScrollView的容器 * * @author */ public class ScrollViewContainer extends
RelativeLayout { /** * 自動上滑 */ public static final int AUTO_UP = 0; /** * 自動下滑 */ public static final int AUTO_DOWN = 1; /** * 動畫完成 */ public static final int DONE = 2; /** * 動畫速度 */ public static final float SPEED = 6.5f; private boolean isMeasured = false; /**
* 用於計算手滑動的速度 */ private VelocityTracker vt; private int mViewHeight; private int mViewWidth; private View topView; private View bottomView; private boolean canPullDown; private boolean canPullUp; private int state = DONE; /** * 記錄當前展示的是哪個view,0是topView,1是bottomView */ private int mCurrentViewIndex = 0; /** * 手滑動距離,這個是控制佈局的主要變數 */ private float mMoveLen; private MyTimer mTimer; private float mLastY; /** * 用於控制是否變動佈局的另一個條件,mEvents==0時佈局可以拖拽了,mEvents==-1時可以捨棄將要到來的第一個move事件, * 這點是去除多點拖動劇變的關鍵 */ private int mEvents; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (mMoveLen != 0) { if (state == AUTO_UP) { mMoveLen -= SPEED; if (mMoveLen <= -mViewHeight) { mMoveLen = -mViewHeight; state = DONE; mCurrentViewIndex = 1; } } else if (state == AUTO_DOWN) { mMoveLen += SPEED; if (mMoveLen >= 0) { mMoveLen = 0; state = DONE; mCurrentViewIndex = 0; } } else { mTimer.cancel(); } } requestLayout(); } }; public ScrollViewContainer(Context context) { super(context); init(); } public ScrollViewContainer(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ScrollViewContainer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mTimer = new MyTimer(handler); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: if (vt == null) vt = VelocityTracker.obtain(); else vt.clear(); mLastY = ev.getY(); vt.addMovement(ev); mEvents = 0; break; case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_UP: // 多一隻手指按下或擡起時捨棄將要到來的第一個事件move,防止多點拖拽的bug mEvents = -1; break; case MotionEvent.ACTION_MOVE: vt.addMovement(ev); if (canPullUp && mCurrentViewIndex == 0 && mEvents == 0) { mMoveLen += (ev.getY() - mLastY); // 防止上下越界 if (mMoveLen > 0) { mMoveLen = 0; mCurrentViewIndex = 0; } else if (mMoveLen < -mViewHeight) { mMoveLen = -mViewHeight; mCurrentViewIndex = 1; } if (mMoveLen < -8) { // 防止事件衝突 ev.setAction(MotionEvent.ACTION_CANCEL); } } else if (canPullDown && mCurrentViewIndex == 1 && mEvents == 0) { mMoveLen += (ev.getY() - mLastY); // 防止上下越界 if (mMoveLen < -mViewHeight) { mMoveLen = -mViewHeight; mCurrentViewIndex = 1; } else if (mMoveLen > 0) { mMoveLen = 0; mCurrentViewIndex = 0; } if (mMoveLen > 8 - mViewHeight) { // 防止事件衝突 ev.setAction(MotionEvent.ACTION_CANCEL); } } else mEvents++; mLastY = ev.getY(); requestLayout(); break; case MotionEvent.ACTION_UP: mLastY = ev.getY(); vt.addMovement(ev); vt.computeCurrentVelocity(700); // 獲取Y方向的速度 float mYV = vt.getYVelocity(); if (mMoveLen == 0 || mMoveLen == -mViewHeight) break; if (Math.abs(mYV) < 500) { // 速度小於一定值的時候當作靜止釋放,這時候兩個View往哪移動取決於滑動的距離 if (mMoveLen <= -mViewHeight / 2) { state = AUTO_UP; } else if (mMoveLen > -mViewHeight / 2) { state = AUTO_DOWN; } } else { // 擡起手指時速度方向決定兩個View往哪移動 if (mYV < 0) state = AUTO_UP; else state = AUTO_DOWN; } mTimer.schedule(2); try { vt.recycle(); vt = null;//防止第二次報錯 } catch (Exception e) { e.printStackTrace(); } break; } super.dispatchTouchEvent(ev); return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { topView.layout(0, (int) mMoveLen, mViewWidth, topView.getMeasuredHeight() + (int) mMoveLen); bottomView.layout(0, topView.getMeasuredHeight() + (int) mMoveLen, mViewWidth, topView.getMeasuredHeight() + (int) mMoveLen + bottomView.getMeasuredHeight()); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (!isMeasured) { isMeasured = true; mViewHeight = getMeasuredHeight(); mViewWidth = getMeasuredWidth(); topView = getChildAt(0); bottomView = getChildAt(1); bottomView.setOnTouchListener(bottomViewTouchListener); topView.setOnTouchListener(topViewTouchListener); } } private OnTouchListener topViewTouchListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { ScrollView sv = (ScrollView) v; if (sv.getScrollY() == (sv.getChildAt(0).getMeasuredHeight() - sv .getMeasuredHeight()) && mCurrentViewIndex == 0) canPullUp = true; else canPullUp = false; return false; } }; private OnTouchListener bottomViewTouchListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { ScrollView sv = (ScrollView) v; if (sv.getScrollY() == 0 && mCurrentViewIndex == 1) canPullDown = true; else canPullDown = false; return false; } }; class MyTimer { private Handler handler; private Timer timer; private MyTask mTask; public MyTimer(Handler handler) { this.handler = handler; timer = new Timer(); } public void schedule(long period) { if (mTask != null) { mTask.cancel(); mTask = null; } mTask = new MyTask(handler); timer.schedule(mTask, 0, period); } public void cancel() { if (mTask != null) { mTask.cancel(); mTask = null; } } class MyTask extends TimerTask { private Handler handler; public MyTask(Handler handler) { this.handler = handler; } @Override public void run() { handler.obtainMessage().sendToTarget(); } } } }

2.佈局xml的實現、

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/containerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<!--父容器-->
<com.zjtd.bzcommunity.util.ScrollViewContainer
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom"
android:layout_below="@+id/lintonei"
android:layout_marginBottom="-27dp">
<!--商品詳情-->
<ScrollView
android:id="@+id/mymyscrollview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:scrollbars="none">
            <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
                <RelativeLayoutandroid:id="@+id/layout_product"
android:layout_width="match_parent"
android:layout_height="wrap_content">
                    <ImageView
android:id="@+id/detial_product_img"
android:layout_width="match_parent"
android:layout_height="256dp"
android:background="@mipmap/guanggao3"
android:scaleType="fitXY" />
                    <com.zjtd.bzcommunity.view.SlideShowView
android:id="@+id/chaoshilunboyi"
android:layout_width="match_parent"
android:layout_height="256dp"
android:fitsSystemWindows="true"
android:scaleType="fitXY"
android:src="@drawable/ic_launcher"
android:visibility="gone" />
                </RelativeLayout>
                <View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#f3f2f8" />
                <RelativeLayoutandroid:layout_width="match_parent"
android:layout_height="127dp"
android:background="#ffffff">
                    <RelativeLayoutandroid:id="@+id/layout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/view"
android:orientation="vertical">
                        <TextView
android:id="@+id/detial_product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="17dp"
android:ellipsize="end"
android:lines="2"
android:maxLines="2"
android:text="暫無商品 "
android:textColor="#262626"
android:textSize="16dp" />
                        <TextView
android:id="@+id/detial_product_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/detial_product_name"
android:layout_marginLeft="12dp"
android:layout_marginTop="6dp"
android:text="已售00件"
android:textColor="#999999"
android:textSize="12dp" />
                        <RelativeLayoutandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="15dp"
android:layout_marginRight="17dp">
                            <TextView
android:id="@+id/textjrgwc"
android:layout_width="105dp"
android:layout_height="33dp"
android:background="@drawable/csspxqjrgwc"
android:gravity="center"
android:text="加入購物車"
android:textColor="#ffffff"
android:textSize="14dp"
android:visibility="gone" />
                            <LinearLayout
android:id="@+id/linearjjgwc"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
                                <TextView
android:id="@+id/tvMinus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/button_minus"
android:clickable="true"
android:gravity="center" />
                                <TextView
android:id="@+id/count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="3dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:gravity="center"
android:text="0"
android:textColor="#1a1a1a"
android:textSize="18dp" />
                                <TextView
android:id="@+id/tvAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="7dp"
android:background="@mipmap/button_add"
android:clickable="true"
android:gravity="center" />
                            </LinearLayout>
                        </RelativeLayout>
                        <TextView
android:id="@+id/detial_product_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/detial_product_num"
android:layout_marginLeft="12dp"
android:layout_marginTop="15dp"
android:text="¥0.00"
android:textColor="#f33637"
android:textSize="18dp"
android:textStyle="bold" />
                        <TextView
android:id="@+id/textyuanjia"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/detial_product_num"
android:layout_marginLeft="12dp"
android:layout_marginTop="19dp"
android:layout_toRightOf="@+id/detial_product_price"
android:text="原價:"
android:textSize="12dp" />
                        <TextView
android:id="@+id/zhejia"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/detial_product_num"
android:layout_marginTop="19dp"
android:layout_toRightOf="@+id/textyuanjia"
android:text="¥0.00"
android:textSize="12dp" />
                    </RelativeLayout>
                </RelativeLayout>
                <View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#d9d9d9" />
                <RelativeLayoutandroid:layout_width="match_parent"
android:layout_height="140dp"
android:visibility="gone">
                    <TextView
android:id="@+id/textspgg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="16dp"
android:textColor="#676767"
android:textSize="14dp" />
                </RelativeLayout>
                <RelativeLayoutandroid:layout_width="match_parent"
android:layout_height="110dp"
android:visibility="gone">
                    <TextView
android:id="@+id/textname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="21dp"
android:textColor="#262626"
android:textSize="14dp" />
                    <TextView
android:id="@+id/textdz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textname"
android:layout_marginLeft="12dp"
android:layout_marginTop="12dp"
android:maxLength="20"
android:textColor="#989898"
android:textSize="13dp" />
                    <RelativeLayoutandroid:id="@+id/relativedh"
android:layout_width="64dp"
android:layout_height="37dp"
android:layout_alignParentRight="true"
android:layout_below="@+id/textname">
                        <TextView
android:layout_width="1dp"
android:layout_height="fill_parent"
android:background="#d8d8d8" />
                        <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@mipmap/icon_iphone" />
                    </RelativeLayout>
                    <ImageView
android:id="@+id/imagdw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textdz"
android:layout_marginLeft="10dp"
android:layout_marginTop="11dp"
android:src="@mipmap/ic_global_landmark_groupon_list" />
                    <TextView
android:id="@+id/textmishu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textdz"
android:layout_marginLeft="5dp"
android:layout_marginTop="12dp"
android:layout_toRightOf="@+id/imagdw"
android:textColor="#999999"
android:textSize="13dp" />
                </RelativeLayout>
                <View
android:layout_width="match_parent"
android:layout_height="9dp"
android:background="#f2f2f2" />
                <RelativeLayoutandroid:id="@+id/linearpl"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="vertical">
                    <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:text="商品評價"
android:textColor="#303030"
android:textSize="15dp" />
                    <TextView
android:id="@+id/textsong_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android