UI自定义控件

Android使用DrawerLayout仿京东商品详情中查看更

2021-07-16  本文已影响0人  馒头炖土豆

具体竞品效果请打开京东APP Android端,进入商品详情页面查看


image.png

具体代码如下:

Activity:

import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.*
import androidx.drawerlayout.widget.DrawerLayout

class CommentActivity : BaseActivity(),View.OnClickListener{
    private lateinit var binding: ShopCommentActivityBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ShopCommentActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)

        initView()
        setDraw()
    }
    private fun initView()
    {
        binding.tvMore.setOnClickListener(this)
        binding.tvBottom.setOnClickListener(this)
        binding.tvContentDraw.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.tv_more -> showDraw()
            R.id.tv_bottom -> ToastUtils.show("底部区域")
            R.id.tv_content_draw -> ToastUtils.show("抽屉内容")
        }
    }

    private fun showDraw()
    {
        binding.drawLayout.openDrawer(binding.llContentDraw, true)
    }

    private fun closeDraw()
    {
        binding.drawLayout.closeDrawer(binding.llContentDraw, true)
    }

    //设置抽屉
    private fun setDraw()
    {
        val wm: WindowManager = this.windowManager //获取屏幕宽高
        val width1: Int = wm.getDefaultDisplay().getWidth()
        val para = binding.llContentDraw.getLayoutParams()
        //获取drawerlayout的布局
        para.width = width1 //修改宽度
        binding.llContentDraw.setLayoutParams(para) //设置修改后的布局。
        binding.drawLayout.setScrimColor(Color.TRANSPARENT) //去除遮住主布局的阴影效果
        binding.drawLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) //禁止手势滑出

        binding.llContentDraw.setOnDealTouchEvent(object : MyDrawerLinerLayout.OnDealTouchEvent{
            override fun onDetal() {
                closeDraw()
            }
        })
    }
}

Activity的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<MyDrawerLayout
    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:layout_width="match_parent"
    android:orientation="vertical"
    tools:openDrawer="right"
    android:id="@+id/draw_layout"
    android:layout_height="match_parent">
    <FrameLayout
        android:background="@color/white"
        android:id="@+id/fragment_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:background="#4caf65"
                android:textColor="@color/white"
                android:gravity="center"
                android:text="标题"
                android:layout_width="match_parent"
                android:layout_height="45dp"/>
            <View
                android:layout_weight="1"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_0"/>
            <TextView
                android:background="#4caf65"
                android:layout_gravity="center_horizontal"
                android:textSize="@dimen/dp_20"
                android:textColor="@color/black"
                android:gravity="center"
                android:text="查看更多"
                android:id="@+id/tv_more"
                android:layout_width="@dimen/dp_100"
                android:layout_height="@dimen/dp_50"/>
            <View
                android:layout_weight="1"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_0"/>
            <TextView
                android:id="@+id/tv_bottom"
                android:background="@color/white"
                android:textColor="@color/black"
                android:gravity="center"
                android:text="底部"
                android:layout_width="match_parent"
                android:layout_height="80dp"/>
        </LinearLayout>
    </FrameLayout>
    <MyDrawerLinerLayout
        android:clickable="true"
        android:background="@color/transparent"
        android:id="@+id/ll_content_draw"
        android:layout_marginTop="45dp"
        android:layout_marginBottom="80dp"
        android:layout_gravity="right"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:background="@color/red"
                android:textSize="@dimen/dp_20"
                android:textColor="@color/white"
                android:gravity="center"
                android:text="更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容\n更多内容"
                android:id="@+id/tv_content_draw"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </ScrollView>

    </MyDrawerLinerLayout>

</MyDrawerLayout>

自定义DrawerLayout:

class MyDrawerLayout : DrawerLayout {
    constructor(context: Context) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        return if (isDrawerOpen(Gravity.RIGHT)) //当抽屉展示出来的时候,不拦截触摸事件,防止点击抽屉之外的区域抽屉消失
        {
            false
        } else {
            super.onInterceptTouchEvent(ev)
        }
    }
}

自定义LinearLayout

class MyDrawerLinerLayout : LinearLayout {

    private var downX = 0f //抽屉内容区域手指的点击位置
    private var downY = 0f //抽屉内容区域手指的点击位置
    private lateinit var onDealTouchEvent: OnDealTouchEvent;

    constructor(context: Context) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        when (event?.getAction()) {
            MotionEvent.ACTION_DOWN -> {
                downX = event.getX()
                downY = event.getY()
            }
            MotionEvent.ACTION_MOVE -> {
                val curX: Float = event.getX()
                val curY: Float = event.getY()

                val xDistance = Math.abs(curX - downX);
                val yDistance = Math.abs(curY - downY);

                /**
                 * X轴滑动距离大于Y轴滑动距离,也就是用户横向滑动时,拦截这次事件
                 */
                if (xDistance > yDistance) {
                    return true
                }
            }
            MotionEvent.ACTION_UP -> {
            }
            else -> {
            }
        }
        return super.onInterceptTouchEvent(event)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.getAction()) {
            MotionEvent.ACTION_DOWN -> {
                downX = event.getX()
                downY = event.getY()
            }
            MotionEvent.ACTION_MOVE -> {
                val currentX: Float = event.getX()
                val currentY: Float = event.getY()
                //X轴移动距离超过50px,Y轴移动距离不超过50,表示是横向移动,则让抽屉消失,否则不消失
                if (currentX - downX > 50 && (currentY - downY < 50 || currentY - downY > -50)) {
                    if (onDealTouchEvent != null)
                    {
                        onDealTouchEvent.onDetal() //处理触摸事件
                    }
                    return true
                }
            }
            MotionEvent.ACTION_UP -> {
            }
            else -> {
            }
        }
        return super.onTouchEvent(event)
    }

    interface OnDealTouchEvent{
        fun onDetal();
    }

    fun setOnDealTouchEvent(onDealTouchEvent: OnDealTouchEvent)
    {
        this.onDealTouchEvent = onDealTouchEvent;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读