岩松YanSong 2019-11-20 17:07 采纳率: 0%
浏览 237

如何使组合控件可悬浮拖动实现返回顶部的功能?(问题已经解决,原因是FloatingView写的有问题)

我有一个创建了一个组合控件,然后想让这个组合控件在页面内随意拖动实现返回顶部的功能,然后FloatingView继承了这个组合控件后,使用报运行时异常,请问我该怎么修改?谢谢

下面是组合控件:

public class BackTopView extends RelativeLayout {
   private TextView text_view;
   private View rootView;
   private String back_text;


    public BackTopView(Context context) {
        super(context);
        init();
    }

    public BackTopView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

        back_text=attrs.getAttributeValue("http://schemas.android.com/apk/res-auto","setting_text");

        text_view.setText(back_text);

    }

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

    private void init(){
        rootView=View.inflate(getContext(), R.layout.back_top_layout,this);
        text_view=rootView.findViewById(R.id.back_text);
    }

    public void setText(String text){
        text_view.setText(text);
    }

}

下面是悬浮实现

public class FloatingView extends BackTopView {

    int startX;
    int startY;
    int left;
    int top;
    int[] temp = new int[]{ 200, 200 };

    public FloatingView(Context context) {
        super(context);
    }



    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean isMove = false;
        int x = (int) event.getRawX();
        int y = (int) event.getRawY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN: // touch down so check if the
                startX = x;
                startY = y;
                temp[0] = (int) event.getX();
                temp[1] = y - getTop();
                break;
            case MotionEvent.ACTION_MOVE: // touch drag with the ball
                left = x - temp[0];
                top = y - temp[1];
                if(left < 0){//控制左边界不超出
                    left = 0;
                }
                layout(left, top, left + getWidth(),top + getHeight());//自由拖拽
                break;
            case MotionEvent.ACTION_UP:
                if (Math.abs(x - startX) > 2 || Math.abs(y - startY) > 2){//判断是否移动,再一定范围内不算是移动,解决触发事件冲突
                    //将最后拖拽的位置定下来,否则页面刷新渲染后按钮会自动回到初始位置
                    //注意父容器
                    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
                    lp.setMargins(left, top,0,0);
                    setLayoutParams(lp);
                    //确定是拖拽
                    isMove = true;
                }
                break;
        }
        return isMove ? true : super.onTouchEvent(event);
    }
}

引用到的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"
    android:id="@+id/first_layout"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".AssetsActivity"
    android:orientation="vertical"
    android:clickable="true"
    android:focusableInTouchMode="true">

    <RelativeLayout
        android:id="@+id/edit_relativew"
        android:layout_marginTop="15dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@drawable/edit_frame_shape">

        <EditText
            android:id="@+id/assets_edit"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="15dp"
            android:background="@null"
            android:hint=" 搜索设备"
            android:imeOptions="actionSearch"
            android:singleLine="true"></EditText>

        <ImageButton
            android:id="@+id/assets_btu"
            android:layout_alignRight="@id/assets_edit"
            android:layout_centerVertical="true"
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_gravity="center"
            android:background="@drawable/select">

        </ImageButton>

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/edit_relativew"
        android:layout_marginTop="10dp"
        android:orientation="vertical">

        <com.zxkj.e_delivermaintain.Adapter.LoadListView
            android:id="@+id/assets_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@null">

        </com.zxkj.e_delivermaintain.Adapter.LoadListView>

    </RelativeLayout>

    <include
        android:id="@+id/emptyview"
        layout="@layout/list_empty"/>

    <com.zxkj.e_delivermaintain.Adapter.FloatingView
        android:id="@+id/back_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center">

    </com.zxkj.e_delivermaintain.Adapter.FloatingView>


</RelativeLayout>

报错内容

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.zxkj.e_delivermaintain/com.zxkj.e_delivermaintain.AssetsActivity}: android.view.InflateException: Binary XML file line #68: Binary XML file line #68: Error inflating class com.zxkj.e_delivermaintain.Adapter.FloatingView

谢谢你的帮助!!

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-07-29 13:14
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    要解决这个问题,首先确保FloatingView类正确地实现了OnTouchListener接口,并且它能够正确处理触摸事件。此外,你需要确保在FloatingView中设置了正确的布局参数以支持拖动功能。

    以下是修复后的FloatingView代码:

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.RelativeLayout;
    
    public class FloatingView extends RelativeLayout implements OnTouchListener {
    
        private Context mContext;
        private float mLastX;
        private float mLastY;
        private float mTouchSlop = 10; // 设置触摸敏感度范围
    
        public FloatingView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public FloatingView(Context context) {
            this(context, null);
        }
    
        protected void onFinishInflate() {
            super.onFinishInflate();
            initViews();
        }
    
        private void initViews() {
            RelativeLayout rootLayout = findViewById(R.id.root_layout);
            addView(rootLayout);
    
            mLastX = mLastY = 0;
            rootLayout.setOnTouchListener(this);
        }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mLastX = event.getX();
                    mLastY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    move(v, event);
                    break;
                case MotionEvent.ACTION_UP:
                    if (isOverThreshold(mLastX, mLastY)) {
                        onDragEnd();
                    } else {
                        onDragStart();
                    }
                    mLastX = mLastY = 0;
                    break;
            }
            return true;
        }
    
        private boolean isOverThreshold(float lastX, float lastY) {
            return Math.abs(lastX - mLastX) > mTouchSlop || Math.abs(lastY - mLastY) > mTouchSlop;
        }
    
        private void move(View view, MotionEvent event) {
            float dx = event.getX() - mLastX;
            float dy = event.getY() - mLastY;
    
            // 调整布局参数
            ((RelativeLayout) view).setTranslationX(dx);
            ((RelativeLayout) view).setTranslationY(dy);
    
            mLastX = event.getX();
            mLastY = event.getY();
        }
    
        private void onDragStart() {
            // 处理开始拖动的行为
        }
    
        private void onDragEnd() {
            // 处理结束拖动的行为
        }
    }
    
    // 假设你已经添加了适配器和视图
    private com.zxkj.e_delivermaintain.Adapter.FloatingView floatingView = new com.zxkj.e_delivermaintain.Adapter.FloatingView(mContext);
    

    现在,FloatingView应该能够在页面上进行拖动并实现返回顶部的功能了。

    评论

报告相同问题?