仿淘宝商品详情页,上拉查看更多详情demo(Activity和Fragment)。2种应用场景

项目需求中实现了一个仿淘宝商品详情页的功能,页面上部分显示文字信息,下部分通过上拉加载WebView。分享了自定义布局SlideDetailsLayout的修改版,适用于Activity和Fragment。文章提供了相关代码示例,包括网络权限设置、自定义属性、回调接口和核心代码实现。
摘要由CSDN通过智能技术生成

最近项目中有个功能,在课程播放页,有个讲师详情页:上面展示文字信息,下面展示一个webView,但是webView,要通过上拉才出现。网上找的一个开源的demo。对里面进行了一定的修改,以符合项目要求:

https://github.com/cnbleu/SlideDetailsLayout

注:
**1、滑动的自定义布局 SlideDetailsLayout 中,只包含2个子view。多了会有问题
2、如果第一个默认展示的view没有被填满,会有留白。详见效果图**

以下会对在Activity中,已经在Fragment中使用,分别附上源码(代码、布局文件)

—————————————————————————————————
效果图:
1、Activity中使用:
这里写图片描述

2、Fragment中使用
这里写图片描述

3、默认展示控件中的数据没有完全填充
这里写图片描述

代码:
1、因为有webView,先加上网络权限:

<uses-permission android:name="android.permission.INTERNET"/>

2、有自定义属性,所以,需要在 values文件夹下,创建 attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="SlideDetailsLayout">
        <!-- float value for indicate the moment of switch panel-->
        <attr name="percent" format="float"/>
        <!-- how long the animation keep-->
        <attr name="duration" format="integer"/>
        <!-- default panel to show after init-->
        <attr name="default_panel" format="enum">
            <enum name="front" value="0"/>
            <enum name="behind" value="1"/>
        </attr>
    </declare-styleable>

</resources>

3、回调接口

/**
 * 滑动回调接口
 */
public interface ISlideCallback {
   

    //展开详情
    void openDetails(boolean smooth);

    //关闭详情
    void closeDetails(boolean smooth);
}

4、最核心的代码:SlideDetailsLayout


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.AbsListView;

/**
 * 滑动的自定义view
 */
public class SlideDetailsLayout extends ViewGroup {
   

    /**
     * Callback for panel OPEN-CLOSE status changed.
     */
    public interface OnSlideDetailsListener {
   
        /**
         * Called after status changed.
         *
         * @param status {@link Status}
         */
        void onStatucChanged(Status status);
    }

    /**
     * 状态值
     */
    public enum Status {
        CLOSE,
        OPEN;

        public static Status valueOf(int stats) {
            if (0 == stats) {
                return CLOSE;
            } else if (1 == stats) {
                return OPEN;
            } else {
                return CLOSE;
            }
        }
    }

    //默认百分比
    private static final float DEFAULT_PERCENT = 0.2f;
    //默认执行时间
    private static final int DEFAULT_DURATION = 300;
    //默认最大速度
    private static final float DEFAULT_MAX_VELOCITY = 2500f;

    private View mFrontView;
    private View mBehindView;

    private float mTouchSlop;
    private float mInitMotionY;
    private float mInitMotionX;


    private View mTarget;
    private float mSlideOffset;
    private Status mStatus = Status.CLOSE;
    private boolean isFirstShowBehindView = true;
    private float mPercent = DEFAULT_PERCENT;
    private long mDuration = DEFAULT_DURATION;
    private int mDefaultPanel = 0;
    private VelocityTracker mVelocityTracker;

    private OnSlideDetailsListener mOnSlideDetailsListener;

    public SlideDetailsLayout(Context context) {
        this(context, null);
    }

    public SlideDetailsLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlideDetailsLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideDetailsLayout, defStyleAttr, 0);
        mPercent = a.getFloat(R.styleable.SlideDetailsLayout_percent, DEFAULT_PERCENT);
        mDuration = a.getInt(R.styleable.SlideDetailsLayout_duration, DEFAULT_DURATION);
        mDefaultPanel = a.getInt(R.styleable.SlideDetailsLayout_default_panel, 0);
        a.recycle();

        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    }

    /**
     * Set the callback of panel OPEN-CLOSE status.
     *
     * @param listener {@link OnSlideDetailsListener}
     */
    public void setOnSlideDetailsListener(OnSlideDetailsListener listener) {
        this.mOnSlideDetailsListener = listener;
    }

    /**
     * Open pannel smoothly.
     *
     * @param smooth true, smoothly. false otherwise.
     */
    public void smoothOpen(boolean smooth) {
        if (mStatus != Status.OPEN) {
            mStatus = Status.OPEN;
            final float height = -getMeasuredHeight();
            animatorSwitch(0, height, true, smooth ? mDuration : 0);
        }
    }

    /**
     * Close pannel smoothly.
     *
     * @param smooth true, smoothly. false otherwise.
     */
    public void smoothClose(boolean smooth) {
        if (mStatus != Status.CLOSE) {
            mStatus = Status.OPEN;
            final float height = -getMeasuredHeight();
            animatorSwitch(height, 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值