viewpager里的安卓控件移动和单击事件解决

本文介绍了如何在Android的ViewPager中处理控件的移动和单击事件。通过实现OnTouchListener接口,记录ACTION_DOWN和ACTION_MOVE事件,动态调整控件的位置并重绘。同时,注意到ViewPager自身滑动时不应改变控件位置,因此需要保存初始位置并在合适时机恢复。还提到了SharedPreferences的使用模式,并引用了相关博客资源进行进一步学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 一、实例化控件,设置监听

        maction = (ImageView) findViewById(R.id.action_icon);
        //移动小球的类
        toucherActionIcon = new ToucherActionIcon();
        maction.setOnTouchListener(toucherActionIcon);

二、实现触碰接口然后在里面实现移动+重绘和单击事件

实现了OnTouchListener接口,覆写了onTouch方法,每次回调这个方法通过x和y变量记录当前的坐标。

ACTION_DOWN是在按下的时候调用(没抬起来只调用一次),通过xDelta和yDelta来记录第一次按下的点相对于控件左上角的位置,也就是相对距离。

ACTION_MOVE移动的时候不断调用,通过xDistance和yDistance来记录移动的相对距离作为leftMargin和topMargin再动态设置给控件。

最后,调用invalidate方法更新控件位置。

 /**
     * class name : ToucherActionIcon
     * Specific description :actionbutton的移动和单击事件解决
     */
    public class ToucherActionIcon implements View.OnTouchListener{
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            final int x = (int) event.getRawX();
            final int y = (int) event.getRawY();
            LogUtils.d(TAG, "onTouch: x= " + x + "y=" + y);
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view
                            .getLayoutParams();
                    xDelta = x - params.leftMargin;
                    yDelta = y - params.topMargin;
                    startTime = System.currentTimeMillis();
                    LogUtils.d("开始时间:" + startTime);
                    LogUtils.d(TAG, "ACTION_DOWN: xDelta= " + xDelta + "yDelta=" + yDelta);
                    break;
                case MotionEvent.ACTION_MOVE:
                    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
                            .getLayoutParams();
                    int xDistance = x - xDelta;
                    int yDistance = y - yDelta;
                    LogUtils.d(TAG, "ACTION_MOVE: xDistance= " + xDistance + "yDistance=" + yDistance);
                    layoutParams.leftMargin = xDistance;
                    layoutParams.topMargin = yDistance;
                    view.setLayoutParams(layoutParams);
                    break;
                case MotionEvent.ACTION_UP:// 手指离开屏幕对应事件
                    // 记录最后图片在窗体的位置
                    endTime = System.currentTimeMillis();
                    LogUtils.d("结束时间:" + endTime);
                    //当从点击到弹起小于半秒的时候,则判断为点击,如果超过则不响应点击事件
                    if ((endTime - startTime) > 0.1 * 1000L) {
                        isclick = false;
                    } else {
                        isclick = true;
                    }
                    System.out.println("执行顺序up");
                    if (isclick) {
                        Intent intent = new Intent(ReadActivity.this, MainActivity.class);
                        startActivity(intent);
                    }
                    break;
            }


            mViewGroup.invalidate();
            return true;
        }

注意:

viewpager不能用这样的方式来重绘控件,本来viewpager滑动控件的位置也不应该变的,但是变回原来开始控件我xml规定的位置。

                    // 更新界面
                    ivDrag.layout(l, t, r, b);

 所以我就想那我存起来,再画到这里。

    SharedPreferences支持三种模式:

  • MODE_PRIVATE:只支持本程序读写
  • MODE_WORLD_READABLE:允许其它应用程序读
  • MODE_WORLD_WRITEABLE :允许其它应用程序写
    /**
     * Method name :
     * Specific description :存简单数据 小球的位置
     *@return
     */
    public void saveData(int ml,int mt,int mr, int mb,int mx, int my){
        SharedPreferences sp=this.getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor editor=sp.edit();
        editor.putInt("l",ml );
        editor.putInt("t",mt );
        editor.putInt("l",mr );
        editor.putInt("t",mb );
        editor.putInt("x",mx );
        editor.putInt("y",my );
        LogUtils.d("缓存里面:l"+ml+",t"+mt+",r"+mr+",b"+mb+",x"+mx+",y"+my);
        editor.commit();
    }
        /**
         * 页面跳转完毕的时候调用
         * @param position 选中的页面的Position(位置编号)
         */
        @Override
        public void onPageSelected(int position) {
            // 更新界面
            int mtl=sp.getInt("l",30);
            int mtt=sp.getInt("t",70);
            int mtr=sp.getInt("r",70);
            int mtb=sp.getInt("b",70);
            int mtx = sp.getInt("x",70);
            int mty = sp.getInt("y",70);
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.leftMargin = mtx;
            layoutParams.topMargin = mty;
            maction.setLayoutParams(layoutParams);
//            maction.layout( mtt, mtr,mtl, mtb);
            LogUtils.d("下一个页面了:l"+mtl+",t"+mtt+",r"+mtr+",b"+mtb+",b"+mtx+",b"+mty);

        }

 通过在控制台打印过,我猜想是viewpager属于一个宽宽的东西,他的这些margin是针对全局的,因为已经到了下一pager,他已经不在原来的位置,于是只能画到了我xml设定的位置。

 

其他的:

感谢:

https://blog.youkuaiyun.com/yayun0516/article/details/52254818

https://blog.youkuaiyun.com/sdlg2015/article/details/49933243

单单是双击事件:

https://blog.youkuaiyun.com/lpCrazyBoy/article/details/79873437

Android 手势识别(单击 双击 抬起 短按 长按 滚动 滑动):

https://blog.youkuaiyun.com/qq_30380777/article/details/53066906

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值