HorizontalScrollDemo-master icon indicating copy to clipboard operation
HorizontalScrollDemo-master copied to clipboard

判断导致子View点击事件不触发,需要去掉

Open getglory opened this issue 3 years ago • 5 comments

CustomHorizontalScrollView里的onInterceptTouchEvent方法中加了 if (eventListener!=null){ return true; } 判断会导致子View点击事件不触发,需要去掉

getglory avatar Jan 05 '21 03:01 getglory

楼主,eventListener是想通过topTab的滑动来调动整个右侧的联动滑动吧,子View点击失效怎么解决?

Forward0908 avatar Jun 03 '21 06:06 Forward0908

楼主,eventListener是想通过topTab的滑动来调动整个右侧的联动滑动吧,子View点击失效怎么解决?

我是这么改的:

public class CustomHorizontalScrollView extends HorizontalScrollView { private OnCustomScrollChangeListener listener; private CustomClickListener clickListener;

public interface OnCustomScrollChangeListener {
    void onCustomScrollChange(CustomHorizontalScrollView listener, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
}

public void setOnCustomScrollChangeListener(OnCustomScrollChangeListener listener) {
    this.listener = listener;
}

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

public CustomHorizontalScrollView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();//返回一个int类型,表示一个距离--->滑动的时候,手的移动要大于这个距离才开始移动控件。
}

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

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);
    if (null != listener)
        listener.onCustomScrollChange(CustomHorizontalScrollView.this, l, t, oldl, oldt);
}

public void setEventListener(EventListener listener) {
    eventListener = listener;
}

private EventListener eventListener = null;

public interface EventListener {
    void onEvent(MotionEvent event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

// if (eventListener!=null){ // return true; // } return super.onInterceptTouchEvent(ev); }

private float startY;
private float startX;
private int mTouchSlop;
private boolean intercept;

@Override
public boolean onTouchEvent(MotionEvent ev) {
    /*onTouch事件中:down事件返回值标记此次事件是否为点击事件
    (返回false,是点击事件;返回true,不记为点击事件),而up事件标记此次事件结束时间,也就是判断是否为长按。
    只要当down返回true时候,系统将不把本次事件记录为点击事件,也就不会触发onClick或者onLongClick事件了。
    因此尽管当up的时候返回false,系统也不会继续触发onClick事件了。*/
    int action = ev.getAction();
    switch (action) {
        case MotionEvent.ACTION_DOWN:
            intercept = false;
            startY = ev.getY();
            startX = ev.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            float endY = ev.getY();
            float endX = ev.getX();
            float distanceX = Math.abs(endX - startX);
            float distanceY = Math.abs(endY - startY);
            if (distanceX > mTouchSlop && distanceX > distanceY) {
                intercept = true;
                getParent().requestDisallowInterceptTouchEvent(true);
            } else {
                getParent().requestDisallowInterceptTouchEvent(false);
            }
            break;
        case MotionEvent.ACTION_UP:
            if (!intercept && clickListener != null) {
                clickListener.onClick();
            }
            break;
    }
    if (eventListener != null) {
        eventListener.onEvent(ev);
        return true;
    } else {
        return super.onTouchEvent(ev);
    }
}

public void setCustomClickListener(CustomClickListener listener) {
    this.clickListener = listener;
}

public interface CustomClickListener  {
    void onClick();
}

}

getglory avatar Jun 03 '21 06:06 getglory

楼主,eventListener是想通过topTab的滑动来调动整个右侧的联动滑动吧,子View点击失效怎么解决?

Activity里的代码: mAdapter.setOnContentScrollListener(new GoodsMonitorAdapter.OnContentScrollListener() { @Override public void onScroll(MotionEvent event) { //处理单个item滚动时,顶部tab需要联动 if (null != horScrollview) horScrollview.onTouchEvent(event); } }); //滚动RV时,同步所有横向位移的item rvMonitor.addOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            List<GoodsMonitorHolder> viewHolderCacheList = mAdapter.getViewHolderCacheList();
            if (null != viewHolderCacheList) {
                int size = viewHolderCacheList.size();
                for (int i = 0; i < size; i++) {
                    viewHolderCacheList.get(i).getView(R.id.hor_scrollview).scrollTo(mAdapter.getOffestX(), 0);
                }
            }

        }
    });

    //同步顶部tab的横向scroll和内容页面的横向滚动
    //同步滚动顶部tab和内容
    horScrollview.setOnCustomScrollChangeListener(new CustomHorizontalScrollView.OnCustomScrollChangeListener() {

        private boolean isVisible;
        private boolean needSetVisibility;//RecyclerView的item是否需要重置阴影

        @Override
        public void onCustomScrollChange(CustomHorizontalScrollView listener, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            if (isVisible != horScrollview.canScrollHorizontally(1)) {
                isVisible = horScrollview.canScrollHorizontally(1);
                viewShadow.setVisibility(isVisible ? View.VISIBLE : View.GONE);
                needSetVisibility = true;
            }

            //代码重复,可以抽取/////
            mAdapter.offestX = scrollX;
            List<GoodsMonitorHolder> viewHolderCacheList = mAdapter.getViewHolderCacheList();
            if (null != viewHolderCacheList) {
                int size = viewHolderCacheList.size();
                for (int i = 0; i < size; i++) {
                    viewHolderCacheList.get(i).getView(R.id.hor_scrollview).scrollTo(scrollX, 0);
                    if (needSetVisibility) {
                        viewHolderCacheList.get(i).getView(R.id.view_shadow).setVisibility(isVisible ? View.VISIBLE : View.GONE);
                    }
                    if (i == size - 1) {
                        needSetVisibility = false;//设置完最后一个item的阴影状态,将标志重置为false
                    }
                }
            }
        }

    });

getglory avatar Jun 03 '21 06:06 getglory

楼主,eventListener是想通过topTab的滑动来调动整个右侧的联动滑动吧,子View点击失效怎么解决?

Adapter的代码,之前用了多个item,后来改成同一个了,懒得区分了。点击好像还是有问题,通过UI设计其他样式规避了,具体忘了。。里面一些不相关的设置文字、宽高的代码就不用看了: /**

  • TODO 设置了子View的点击事件时,手指在子View上无法滑动,后期考虑改成使用两个RecyclerView来实现

  • Create by Allan_Zhang at 2021/01/04 17:50 */ public class GoodsMonitorAdapter extends CustomMultiItemAdapter<IItemType, GoodsMonitorHolder> { private List<GoodsMonitorHolder> mViewHolderList = new ArrayList<>(); public int offestX = 0; private OnContentScrollListener onContentScrollListener; private OnCustomClickListener onCustomClickListener; private Paint mMeasurePaint;

    public GoodsMonitorAdapter(List<IItemType> data) { super(data); addItemType(IItemType.TYPE_CONTENT, R.layout.item_goods_coupon_monitor); addItemType(IItemType.TYPE_SUB_CONTENT, R.layout.item_goods_coupon_monitor); mMeasurePaint = new Paint(); }

    @Override protected void convert(@NonNull GoodsMonitorHolder helper, IItemType item) { if (item.getItemType() == IItemType.TYPE_CONTENT) { GoodsCouponMonitorResp.MonitorBean bean1 = (GoodsCouponMonitorResp.MonitorBean) item; helper.setText(R.id.tv_goods_name, checkEmptyText(bean1.name)) .setText(R.id.tv_num, String.valueOf(bean1.num)) .setText(R.id.tv_attached_goods, checkEmptyText(bean1.attachedName)) .setTextColor(R.id.tv_left_num, getColor(bean1.sort == 10 ? R.color.c3 : R.color.color_text_red)) .setGone(R.id.iv_open, bean1.subList != null && !bean1.subList.isEmpty()) .setImageResource(R.id.iv_open, bean1.isOpened ? R.mipmap.icon_channel_down : R.mipmap.icon_channel_r) .addOnClickListener(R.id.tv_left_num, R.id.iv_info, R.id.iv_info2); TextView tvGoodsName = helper.getView(R.id.tv_goods_name); if (bean1.name != null) { float lines = measureTextLength(tvGoodsName, bean1.subList != null && !bean1.subList.isEmpty(), false); helper.setGone(R.id.iv_info, lines > 2); } else { helper.setGone(R.id.iv_info, false); } TextView tvAttachedGoods = helper.getView(R.id.tv_attached_goods); if (bean1.attachedName != null) { float lines = measureTextLength(tvAttachedGoods, false, true); helper.setGone(R.id.iv_info2, lines > 2); } else { helper.setGone(R.id.iv_info2, false); } TextView tvLeftNum = helper.getView(R.id.tv_left_num); if (!TextUtils.isEmpty(bean1.sortName)) { tvLeftNum.setText(bean1.sortName); } else { tvLeftNum.setText(checkEmptyText(bean1.leftNum)); } if (getItemPosition(helper) == getData().size() - 1) { helper.setBackgroundRes(R.id.fl_container, R.drawable.bg_card_bottom); } else { helper.setBackgroundColor(R.id.fl_container, getColor(R.color.app_color_white)); } } else { GoodsCouponMonitorResp.MonitorBean bean2 = (GoodsCouponMonitorResp.MonitorBean) item; helper.setText(R.id.tv_goods_name, checkEmptyText(bean2.name)) .setText(R.id.tv_num, String.valueOf(bean2.num)) .setTextColor(R.id.tv_left_num, getColor(bean2.sort == 10 ? R.color.c3 : R.color.color_text_red)) .setText(R.id.tv_attached_goods, checkEmptyText(bean2.attachedName)) .setGone(R.id.iv_open, false) .addOnClickListener(R.id.iv_info, R.id.iv_info2); TextView tvLeftNum = helper.getView(R.id.tv_left_num); if (!TextUtils.isEmpty(bean2.sortName)) { tvLeftNum.setText(bean2.sortName); } else { tvLeftNum.setText(checkEmptyText(bean2.leftNum)); } TextView tvGoodsName = helper.getView(R.id.tv_goods_name); if (bean2.name != null) { float lines = measureTextLength(tvGoodsName, false, false); helper.setGone(R.id.iv_info, lines > 2); } else { helper.setGone(R.id.iv_info, false); } TextView tvAttachedGoods = helper.getView(R.id.tv_attached_goods); if (bean2.attachedName != null) { float lines = measureTextLength(tvAttachedGoods, false, true); helper.setGone(R.id.iv_info2, lines > 2); } else { helper.setGone(R.id.iv_info2, false); } if (getItemPosition(helper) == getData().size() - 1) { helper.setBackgroundRes(R.id.fl_container, R.drawable.bg_item_goods_coupon_monitor_gray); } else { helper.setBackgroundColor(R.id.fl_container, getColor(R.color.color_f2f2f2)); } } //缓存当前holder if (!mViewHolderList.contains(helper)) { mViewHolderList.add(helper); } CustomHorizontalScrollView horItemScrollview = helper.getView(R.id.hor_scrollview); horItemScrollview.setCustomClickListener(new CustomHorizontalScrollView.CustomClickListener() { @Override public void onClick() { if (DebounceCheckUtil.isDoubleClick()) { return; } if (onCustomClickListener != null) { onCustomClickListener.onClick(getItemPosition(helper)); } } }); horItemScrollview.setEventListener(new CustomHorizontalScrollView.EventListener() { @Override public void onEvent(MotionEvent event) { if (null != onContentScrollListener) onContentScrollListener.onScroll(event); } }); //由于viewHolder的缓存,在1级缓存取出来是2个viewholder,并且不会被重新赋值,所以这里需要处理缓存的viewholder的位移 horItemScrollview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (!helper.isLayoutFinish()) { horItemScrollview.scrollTo(offestX, 0); helper.setLayoutFinish(true); } } }); }

    public List<GoodsMonitorHolder> getViewHolderCacheList() { return mViewHolderList; }

    public int getOffestX() { return offestX; }

    public interface OnContentScrollListener { void onScroll(MotionEvent event); }

    public void setOnContentScrollListener(OnContentScrollListener onContentScrollListener) { this.onContentScrollListener = onContentScrollListener; }

    public interface OnCustomClickListener { void onClick(int position); }

    public void setOnCustomClickListener(OnCustomClickListener onCustomClickListener) { this.onCustomClickListener = onCustomClickListener; }

    /**

    • 判断TextView的字数占几行

    • @return      

    • @param tv */ private float measureTextLength(TextView tv, boolean isPackage, boolean isAttachedGoods) { mMeasurePaint.setTextSize(tv.getTextSize()); int width = getDimensionPixelSize(R.dimen.goods_coupon_monitor_item_width); int offset1 = getDimensionPixelSize(R.dimen.goods_coupon_monitor_offset1); int offset2 = getDimensionPixelSize(R.dimen.goods_coupon_monitor_offset2); int offset3 = getDimensionPixelSize(R.dimen.goods_coupon_monitor_offset3); float textWidth; if (isAttachedGoods) {//关联货品右边距为15 textWidth = width - 2 * offset1; } else { //计算TextView的宽度 textWidth = width - 2 * offset1; if (isPackage) { textWidth = textWidth - offset2 - offset3; } }

      return (mMeasurePaint.measureText(tv.getText() + "") + 0.5f) / textWidth; } }

以下是布局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/fl_container" android:layout_width="match_parent" android:layout_height="58dp" android:background="@color/app_color_white">

<com.yalalat.yuzhanggui.widget.CustomHorizontalScrollView
    android:id="@+id/hor_scrollview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginRight="@dimen/goods_coupon_monitor_sub_item_width"
    android:fillViewport="true"
    android:overScrollMode="never"
    android:scrollbars="none">

    <LinearLayout
        android:id="@+id/ll_monitor"
        android:layout_width="wrap_content"
        android:layout_height="match_parent">

        <FrameLayout
            android:layout_width="@dimen/goods_coupon_monitor_item_width"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:orientation="horizontal"
                android:paddingLeft="15dp">

                <ImageView
                    android:id="@+id/iv_open"
                    android:layout_width="11dp"
                    android:layout_height="11dp"
                    android:layout_marginTop="4dp"
                    android:layout_marginRight="8dp"
                    android:src="@mipmap/icon_channel_r" />

                <TextView
                    android:id="@+id/tv_goods_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="15dp"
                    android:layout_weight="1"
                    android:ellipsize="end"
                    android:gravity="center_vertical"
                    android:maxLines="2"
                    android:textColor="@color/c3"
                    android:textSize="@dimen/s13"
                    tools:text="商品名称最多显示两行超出则截断显示" />

                <ImageView
                    android:id="@+id/iv_info"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="-15dp"
                    android:paddingLeft="8dp"
                    android:paddingTop="3dp"
                    android:paddingRight="8dp"
                    android:paddingBottom="8dp"
                    android:src="@drawable/icon_info"
                    android:visibility="gone"
                    tools:visibility="visible" />


            </LinearLayout>
        </FrameLayout>

        <TextView
            android:id="@+id/tv_num"
            android:layout_width="81dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textColor="@color/c3"
            android:textSize="@dimen/s13"
            tools:text="150" />

        <FrameLayout
            android:layout_width="@dimen/goods_coupon_monitor_item_width"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:orientation="horizontal"
                android:paddingLeft="15dp">

                <TextView
                    android:id="@+id/tv_attached_goods"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="15dp"
                    android:layout_weight="1"
                    android:ellipsize="end"
                    android:maxLines="2"
                    android:textColor="@color/c3"
                    android:textSize="@dimen/s13"
                    tools:text="商品名称最多显示两行超出则截断显示" />

                <ImageView
                    android:id="@+id/iv_info2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="-15dp"
                    android:paddingLeft="8dp"
                    android:paddingTop="3dp"
                    android:paddingRight="8dp"
                    android:paddingBottom="8dp"
                    android:src="@drawable/icon_info"
                    android:visibility="gone"
                    tools:visibility="gone" />

            </LinearLayout>
        </FrameLayout>

    </LinearLayout>

</com.yalalat.yuzhanggui.widget.CustomHorizontalScrollView>

<View
    android:id="@+id/view_shadow"
    android:layout_width="4dp"
    android:layout_height="match_parent"
    android:layout_gravity="right"
    android:layout_marginRight="@dimen/goods_coupon_monitor_sub_item_width"
    android:background="@drawable/shadow_coupon_monitor" />

<TextView
    android:id="@+id/tv_left_num"
    android:layout_width="@dimen/goods_coupon_monitor_sub_item_width"
    android:layout_height="match_parent"
    android:layout_gravity="right"
    android:gravity="center"
    android:textColor="@color/c3"
    android:textSize="@dimen/s13"
    tools:text="150" />

getglory avatar Jun 03 '21 06:06 getglory

楼主,eventListener是想通过topTab的滑动来调动整个右侧的联动滑动吧,子View点击失效怎么解决?

还有个在Activity里的布局。。

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">

        <FrameLayout
            android:id="@+id/fl_top_root"
            android:layout_width="match_parent"
            android:layout_height="@dimen/goods_coupon_monitor_sub_item_height"
            android:layout_marginLeft="12dp"
            android:layout_marginTop="12dp"
            android:layout_marginRight="12dp"
            android:background="@drawable/bg_card_top">

            <com.yalalat.yuzhanggui.widget.CustomHorizontalScrollView
                android:id="@+id/hor_scrollview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginRight="@dimen/goods_coupon_monitor_sub_item_width"
                android:fillViewport="true"
                android:overScrollMode="never"
                android:scrollbars="none">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent">

                    <TextView
                        android:layout_width="146dp"
                        android:layout_height="match_parent"
                        android:gravity="center_vertical"
                        android:paddingLeft="15dp"
                        android:text="商品名称"
                        android:textColor="@color/c6"
                        android:textSize="@dimen/s12" />

                    <TextView
                        android:layout_width="81dp"
                        android:layout_height="match_parent"
                        android:gravity="center"
                        android:text="待核销数"
                        android:textColor="@color/c6"
                        android:textSize="@dimen/s12" />

                    <TextView
                        android:layout_width="146dp"
                        android:layout_height="match_parent"
                        android:gravity="center"
                        android:text="关联货品"
                        android:textColor="@color/c6"
                        android:textSize="@dimen/s12" />
                </LinearLayout>

            </com.yalalat.yuzhanggui.widget.CustomHorizontalScrollView>

            <View
                android:layout_width="match_parent"
                android:layout_height="@dimen/divider_height"
                android:layout_gravity="bottom"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:background="@color/ce" />

            <View
                android:id="@+id/view_shadow"
                android:layout_width="4dp"
                android:layout_height="match_parent"
                android:layout_gravity="right"
                android:layout_marginRight="@dimen/goods_coupon_monitor_sub_item_width"
                android:background="@drawable/shadow_coupon_monitor" />

            <TextView
                android:id="@+id/tv_left_title"
                android:layout_width="@dimen/goods_coupon_monitor_sub_item_width"
                android:layout_height="match_parent"
                android:layout_gravity="right"
                android:gravity="center"
                android:text="剩余库存"
                android:textColor="@color/c6"
                android:textSize="@dimen/s12" />


        </FrameLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_monitor"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:paddingLeft="12dp"
            android:paddingRight="12dp"
            android:paddingBottom="12dp"
            tools:listitem="@layout/item_goods_coupon_monitor" />
    </LinearLayout>

getglory avatar Jun 03 '21 06:06 getglory