【问题标题】:Custom horizontal scroll animation to track finger on view in android自定义水平滚动动画以在 android 中跟踪手指
【发布时间】:2013-04-17 06:05:51
【问题描述】:

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

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

当我决定让项目能够左右滑动以显示像面板这样的设置时,我的问题出现了,它们下方有几个选项(每个项目下面都有自己的设置,而不是所有项目的设置屏幕一种交易)。我四处寻找不同的方法来做到这一点,但似乎找不到一种有效的方法。到目前为止我在想的是有一个HorizonalScrollView,里面有我的项目,设置菜单在屏幕的左侧或右侧,但是当我把我的文本区域放在HorizonalScrollView中时,它只占了一半屏幕,所以我可以并排放置两个,不是我想要的,最终结果也不是我想象的。我真的想要一个允许设置在项目下的解决方案,所以当你把它推开时,它会显示设置。

有没有更好的方法,或者我应该继续尝试让我的HorizonalScrollView 工作,任何关于我如何去做的指南或想法将不胜感激。

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

【问题讨论】:

  • 如果你能发布你想要的图片会更清楚
  • 好吧,我现在把东西放在一起
  • 浏览了我的应用程序,看看是否能找到具有类似功能的应用程序,gmail 应用程序有。这是一个图片链接,可以让您了解一下,在您将项目滑动到一侧后,它会在项目的位置出现一个撤消或存档按钮mobilenewspedia.com/wp-content/uploads/2012/10/…

标签: java android horizontal-scrolling


【解决方案1】:

这个问题是一个相当有趣的话题。并准备好做一定数量的保管工作。

首先,删除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 具有纯色背景。如果您不指定任何背景,则两个 RelativeLayouts 都将可见。另请注意,我使用 RelativeLayout 只是因为我喜欢它们,而且我喜欢它们的灵活性,但这将取决于您的列表视图的内容和您的设置。

当事情变得有趣时,您将需要一个 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(可能在适配器的getView内部)的每个topContent设置一个新的侦听器

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

编辑:

上面的代码是正确的方向,但它是一个 100% 未经测试的东西。 现在下面的代码,我刚刚编译,测试过,这段代码可以工作了!

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

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;
    };
    };
}

【讨论】:

  • 这太好了,你真的超越了。我将开始尝试实现这样的东西,但非常感谢!
  • 嗨。不客气。老实说,我厌倦了阅读 SO 人们询问如何解决 NullPointerException 的问题,很高兴看到像您这样的真实问题。我注意到 GestureDetector 和 SimpleGestureListener 缺少几个事件传递/处理。我刚刚更新了代码。如果它不能立即工作,你可以在这里查看某人的实现stackoverflow.com/questions/10886963/…
  • 不确定您是否会再次看到此内容,但我遇到了视图无法移动的问题,我是否必须更新屏幕上的视图或其他什么?我已经验证我的边距在左右滚动时会发生变化,所以我的问题是该更改没有在屏幕上注册?
  • 从头开始,我刚刚记得你在那里关于需要 requestLayout 的评论,并且在发布后它击中了我。现在,当我左右滚动时,我的视图会移动但会振动。你知道为什么会这样吗?它似乎根本不跟随我的手指......
  • 你可以从头开始,我想出了这个问题,现在我想我有足够的新东西我会问一个新问题,再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 2021-03-16
  • 1970-01-01
  • 2021-04-24
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多