java - 自定义水平滚动动画来跟踪 Android 中 View 上的手指

标签 java android horizontal-scrolling

所以这不是一个关于代码的技术问题,而是更多关于一些想法的问题。我是 Android 开发新手,因此我并不完全熟悉它所提供的很多功能。

屏幕上有一个项目列表,您可以上下滚动以查看不同的项目。

当我决定让项目能够左右滑动以显示诸如面板之类的设置,其下方有一些选项时,我的问题出现了(每个项目下面都有自己的设置,而不是所有项目的设置屏幕)种交易)。我四处寻找不同的方法来做到这一点,但似乎找不到一种有效的方法。到目前为止,我的想法是拥有一个 Horizo​​nalScrollView ,其中包含我的项目,设置菜单位于屏幕左侧或右侧,但是当我将文本区域放入 Horizo​​nalScrollView,它只占据了一半的屏幕,所以我可以并排放置两个,这不是我想要的,最终的结果也不会是我想象的。我真的想要一个允许设置位于项目下方的解决方案,这样当您将其推开时,它就会显示设置。

是否有更好的方法,或者我应该继续尝试让我的 Horizo​​nalScrollView 工作,任何有关我如何解决此问题的指南或想法将不胜感激。

检查我的应用程序,看看是否能找到一个具有类似功能的应用程序,gmail 应用程序有它。这是一个图像链接,可以给您一个想法,将项目滑到一侧后,它会在该项目的位置显示一个撤消或存档按钮,就好像它们隐藏在您滑开的列表项目下一样 enter image description here

最佳答案

这个问题是一个非常有趣的话题。并准备好做一定数量的定制工作。

首先,删除 Horizo​​nalScrollView,我认为它不会对您有帮助。每个项目的布局应该是这样的(伪代码,您可以自己构建 XML =] ):

FrameLayout
   RelativeLayout id:topContent background:someSolidColor
          // inside this RelativeLayout, the stuff that is visible on the ListView
   RelativeLayout id:bottomContent
          // inside this RelativeLayout, the stuff that is behind the content
/FrameLayout

这样一来,您实际上就可以将一件事放在另一件事之上。另请注意,topContent 的背景为纯色。如果您不指定任何背景,则两个相对布局都将可见。另请注意,我使用了RelativeLayout,只是因为我喜欢它们,并且我喜欢它们的灵 active ,但这将取决于您的 ListView 的内容和您的设置。

现在事情变得有趣了,您需要一个 GestureDetector 来检测手指滑动,然后使用该值在 id:topContent 上生成边距偏移。

您可以像这样创建一个 TouchListener:

public class MySlideListener extends View.OnTouchListener{

    private View v;
    private GestureDetector gestureDetector;

    public MySlideListener (View v){
        this.v = v;
        gestureDetector = new GestureDetector(v.getContext(), myGestureListener);
    }

   public boolean onTouch (View v, MotionEvent event){
         return gestureDetector.onTouchEvent(event);
   }

    private SimpleOnGestureListener myGestureListener = new SimpleOnGestureListener(){
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){

           // now here we make the view scroll
           MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
           lp.leftMargin = distanceX;
           lp.rightMargin = -distanceX;

          // You might need to call view.requestLayout();
          //  but first give it a try without it

          // This part of the method for processing the horizontal
          // offset can (and should) be further developed to add some
          // 'snap-in' or transparency functionality to make the whole
          // concept work better.
          // But this code should give you a proof of concept on how to deal with stuff.

          // The important part is that now you have a call back that have access
          // to the view during onScroll.

          // Also might be necessary to enable/disable the bottomContent view
          // in order for it to be not clickable whilst not visible.

           return true;
        }
    }
}

然后使用 topContentView.setOnTouchListener(new MySlideListener(topContentView)); 为 ListView 的每个 topContent 设置一个新的监听器(可能在适配器的 getView 内);

请记住,所有这些代码都是我用心输入的,并且 100% 未经测试!

编辑:

上面的代码是正确的方向,但它是 100% 未经测试的东西。 现在下面的代码,我刚刚编译、测试过,并且该代码可以工作!

该类的效率也更高一些,因为您只能创建一个类,并将相同的实例应用于适配器上创建的所有项目。您可以看到它使 View 在触摸事件上滚动。

public class MySlideListener implements View.OnTouchListener {

    private View view;
    private ListView listView;
    private GestureDetector gestureDetector;

    public MySlideListener(ListView lv) {
        listView = lv;
        gestureDetector = new GestureDetector(lv.getContext(), myGestureListener);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        view = v;
        gestureDetector.onTouchEvent(event);
        return true;
    }

    private SimpleOnGestureListener myGestureListener = new SimpleOnGestureListener() {

    private int origLeft, origRight;

    public boolean onDown(MotionEvent e) {
        MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
        origLeft = lp.leftMargin;
        origRight = lp.rightMargin;
        return true;
    };

    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        listView.requestDisallowInterceptTouchEvent(true);
        MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
        lp.leftMargin = (int) (origLeft + (e2.getRawX() - e1.getRawX()));
        lp.rightMargin = (int) (origRight - (e2.getRawX() - e1.getRawX()));
        view.requestLayout();
        return true;
    };
    };
}

关于java - 自定义水平滚动动画来跟踪 Android 中 View 上的手指,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16179283/

相关文章:

java - 如何检测调用 onClick 处理程序时是否按下了 Shift 键?

android - 使用 "ant debug"构建 osmand 会出错

android - 谷歌标签管理器,安卓。事件仅在应用程序启动时发送

ios - 禁用 iPad 上的水平滚动

java - 为 ref bean 创建属性,Spring

java - 在我重写 onOptionsItemSelected(MenuItem item) 后, onSupportNavigateUp() 不再被触发

java - 下面的泛型代码有什么作用?

java - JTextArea 垂直滚动条在不需要时显示

html - 我的 html 页面包含 3 个表我想水平滚动到其中一个

html - 水平滚动,适合内容宽度