如何使用多个 TouchDelegate
我有两个 ImageButtons,每个都位于relativelayout 内,这两个relativelayout 位于另一个relativelayout 中,我想为每个imagebutton 设置TouchDelegate。如果通常我将 TouchDelegate 添加到每个 ImageButton 并且它是父relativeLayout,那么只有一个 ImageButton 可以正常工作,另一个 ImageButton 不会扩展它的点击区域。因此,请帮助我了解如何在两个 ImageButtons 中使用 TouchDelegate。如果不可能,那么扩展视图的点击区域的有效方法是什么?预先感谢......
这是我的xml代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/FrameContainer"
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout android:layout_alignParentLeft="true"
android:id="@+id/relativeLayout3" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout android:layout_alignParentLeft="true"
android:id="@+id/relativeLayout1" android:layout_width="113dip"
android:layout_height="25dip">
<ImageButton android:id="@+id/tutorial1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="@null" android:src="@drawable/tutorial" />
</RelativeLayout>
<RelativeLayout android:layout_alignParentLeft="true"
android:id="@+id/relativeLayout2" android:layout_width="113dip"
android:layout_height="25dip" android:layout_marginLeft="100dip">
<ImageButton android:id="@+id/tutorial2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="@null" android:src="@drawable/tutorial"
android:layout_marginLeft="50dip" />
</RelativeLayout>
</RelativeLayout>
我的活动课程:
import android.app.Activity;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.TouchDelegate;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
public class TestTouchDelegate extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View mParent1 = findViewById(R.id.relativeLayout1);
mParent1.post(new Runnable() {
@Override
public void run() {
Rect bounds1 = new Rect();
ImageButton mTutorialButton1 = (ImageButton) findViewById(R.id.tutorial1);
mTutorialButton1.setEnabled(true);
mTutorialButton1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(TestTouchDelegate.this, "Test TouchDelegate 1", Toast.LENGTH_SHORT).show();
}
});
mTutorialButton1.getHitRect(bounds1);
bounds1.right += 50;
TouchDelegate touchDelegate1 = new TouchDelegate(bounds1, mTutorialButton1);
if (View.class.isInstance(mTutorialButton1.getParent())) {
((View) mTutorialButton1.getParent()).setTouchDelegate(touchDelegate1);
}
}
});
//View mParent = findViewById(R.id.FrameContainer);
View mParent2 = findViewById(R.id.relativeLayout2);
mParent2.post(new Runnable() {
@Override
public void run() {
Rect bounds2 = new Rect();
ImageButton mTutorialButton2 = (ImageButton) findViewById(R.id.tutorial2);
mTutorialButton2.setEnabled(true);
mTutorialButton2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(TestTouchDelegate.this, "Test TouchDelegate 2", Toast.LENGTH_SHORT).show();
}
});
mTutorialButton2.getHitRect(bounds2);
bounds2.left += 50;
TouchDelegate touchDelegate2 = new TouchDelegate(bounds2, mTutorialButton2);
if (View.class.isInstance(mTutorialButton2.getParent())) {
((View) mTutorialButton2.getParent()).setTouchDelegate(touchDelegate2);
}
}
});
}
}
i have two ImageButtons, each inside a RelativeLayout and these two RelativeLayouts are in another RelativeLayout, i want to set TouchDelegate for each ImageButton. If normally i add TouchDelegate to each ImageButton and it's parent RelativeLayout then just one ImageButton works properly, Another one doesn't extend it's clicking area. So PLease help me on how to use TouchDelegate in both ImageButtons. If it's not possible then what can be a effective way to extend the clicking area of a view? Thanks in advance ........
Here is my xml code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/FrameContainer"
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout android:layout_alignParentLeft="true"
android:id="@+id/relativeLayout3" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout android:layout_alignParentLeft="true"
android:id="@+id/relativeLayout1" android:layout_width="113dip"
android:layout_height="25dip">
<ImageButton android:id="@+id/tutorial1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="@null" android:src="@drawable/tutorial" />
</RelativeLayout>
<RelativeLayout android:layout_alignParentLeft="true"
android:id="@+id/relativeLayout2" android:layout_width="113dip"
android:layout_height="25dip" android:layout_marginLeft="100dip">
<ImageButton android:id="@+id/tutorial2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="@null" android:src="@drawable/tutorial"
android:layout_marginLeft="50dip" />
</RelativeLayout>
</RelativeLayout>
My Activity class :
import android.app.Activity;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.TouchDelegate;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
public class TestTouchDelegate extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View mParent1 = findViewById(R.id.relativeLayout1);
mParent1.post(new Runnable() {
@Override
public void run() {
Rect bounds1 = new Rect();
ImageButton mTutorialButton1 = (ImageButton) findViewById(R.id.tutorial1);
mTutorialButton1.setEnabled(true);
mTutorialButton1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(TestTouchDelegate.this, "Test TouchDelegate 1", Toast.LENGTH_SHORT).show();
}
});
mTutorialButton1.getHitRect(bounds1);
bounds1.right += 50;
TouchDelegate touchDelegate1 = new TouchDelegate(bounds1, mTutorialButton1);
if (View.class.isInstance(mTutorialButton1.getParent())) {
((View) mTutorialButton1.getParent()).setTouchDelegate(touchDelegate1);
}
}
});
//View mParent = findViewById(R.id.FrameContainer);
View mParent2 = findViewById(R.id.relativeLayout2);
mParent2.post(new Runnable() {
@Override
public void run() {
Rect bounds2 = new Rect();
ImageButton mTutorialButton2 = (ImageButton) findViewById(R.id.tutorial2);
mTutorialButton2.setEnabled(true);
mTutorialButton2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(TestTouchDelegate.this, "Test TouchDelegate 2", Toast.LENGTH_SHORT).show();
}
});
mTutorialButton2.getHitRect(bounds2);
bounds2.left += 50;
TouchDelegate touchDelegate2 = new TouchDelegate(bounds2, mTutorialButton2);
if (View.class.isInstance(mTutorialButton2.getParent())) {
((View) mTutorialButton2.getParent()).setTouchDelegate(touchDelegate2);
}
}
});
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
每个视图应该只有一个触摸委托。 View 类中 getTouchDelegate() 的文档如下:
“获取此 View 的 TouchDelegate”。
只能有一个 TouchDelegate。要每个视图仅使用一个 TouchDelegate,您可以将每个可触摸视图包装在一个视图中,其尺寸反映您想要可触摸的内容。 说明如何仅使用一个静态方法对多个视图执行此操作 (http://www.youtube.com/watch?v=jF6Ad4GYjRU&t=37m4s)
:
square 的一位 Android 开发人员给出了一个示例, 不想弄乱你的视图层次结构。我还能想到另外两个选择。您可以定义可触摸视图内可触摸内容的边界,并确保将所有触摸事件从相应的父视图传递到该子视图。或者您可以覆盖可触摸视图的 getHitRect() 。前者会很快使您的代码变得混乱并使其难以理解,因此后者是更好的前进方向。您想要重写 getHitRect。
其中 mPadding 是您希望在视图周围可触摸的额外区域的数量,您可以使用如下所示的内容:
如果您使用类似上面的代码,您将必须考虑附近有哪些可触摸视图。堆栈最高的视图的可触摸区域可能会重叠在另一个视图的顶部。
另一个类似的选项是仅更改可触摸视图的填充。我不喜欢将此作为解决方案,因为跟踪视图大小的调整方式可能会变得困难。
There is only supposed to be one touch delegate for each view. The documentation for getTouchDelegate() in the View class reads:
"Gets the TouchDelegate for this View."
There is only to be one TouchDelegate. To use only one TouchDelegate per view, you can wrap each touchable view within a view with dimensions reflecting what you would like to be touchable. An android developer at square gives an example of how you can do this for multiple Views using just one static method (http://www.youtube.com/watch?v=jF6Ad4GYjRU&t=37m4s):
}
Let's say that you do not want to clutter your view hierarchy. There are two other options I can think of. You can define the bounds of what is touchable inside the touchable view and make sure to pass all touchevents to that child view from respective parent views. Or you can override getHitRect() for the touchable view. The former will quickly clutter your code and make it difficult to understand, so the latter is the better way forward. You want to go with overriding getHitRect.
Where mPadding is the amount of extra area you want to be touchable around your view, you could use something like the following:
If you use code like the above you'll have to consider what touchable views are nearby. The touchable area of the View that is highest on the stack could overlap on top of another View.
Another similar option would be to just change the padding of the touchable view. I dislike this as a solution because it can become difficult to keep track of how Views are being resized.
@need1milliondollars 答案的 Kotlin 版本:
Kotlin version of @need1milliondollars's answer:
完全可用的 Kotlin 扩展功能,允许多个视图将其触摸目标增加相同的量:
Fully working Kotlin extension function which allows for multiple views to increase their touch target by the same amount:
为了使您的代码正常工作,您需要减少
bounds2
的左边框,而不是增加它。在尝试了
TouchDelegate
之后,我找到了下面的代码,它在任何 Android 版本上都适用。诀窍是在调用布局后扩展保证的区域。To make your code working you need to decrease left border of
bounds2
, and not increase it.After playing around with
TouchDelegate
, I came to the code below, which works for me all the time on any Android version. The trick is to extend area guarantied after layout is called.这似乎对我有用 http:// /cyrilmottier.com/2012/02/16/listview-tips-tricks-5-enlarged-touchable-areas/
this seemed to be working for me http://cyrilmottier.com/2012/02/16/listview-tips-tricks-5-enlarged-touchable-areas/
好吧,我想没有人提供真正的答案来解决它并使其变得容易。最近我遇到了同样的问题,阅读了上面的所有内容,我只是不知道如何让它工作。但最后我做到了。首先要记住的事情你的想法!让我们假设你有一个完整的布局,其中包含必须扩展的两个小按钮,因此你必须在主布局中创建另一个布局,并将另一个按钮放入新创建的布局中,因此在这种情况下使用静态方法你可以同时将触摸委托给 2 个按钮现在更深入地一步步进入代码!
首先,您肯定会找到像这样的 MAINLAYOUT 和按钮的视图。(此布局将保存我们的第一个按钮)
好的,我们已经找到主布局及其按钮视图,它将保存所有内容,它只是我们的
onCreate()显示布局,但你必须找到以防万一以后使用它。好的,下一步是什么?我们在主布局中创建另一个RelativeLayout,其宽度和高度符合你的口味(这个新创建的布局将容纳我们的第二个按钮)
好的我们完成了找到视图,这样我们现在就可以复制和粘贴首先回答您问题的人的代码。只需将该代码复制到您的主要活动中即可。
现在如何使用这个方法并使其发挥作用?这就是方法!
在您的
onCreate()
方法上粘贴下一个代码片段解释我们在此片段中所做的事情。我们采用了创建的名为
expandTouchArea()
的静态方法并提供了 3 个参数。第一个参数 - 包含必须扩展区域的按钮的布局
第二个参数 - 扩展其区域的实际按钮
第三个参数 - 我们希望按钮区域扩大多少的区域(以像素为单位)!
享受!
Ok i guess nobody provides the real answer to make solution of it and make it easy.Lately i had same issue and reading all above i just had no clue how just to make it work.But finally i did it.First thing to keep in your mind!Lets pretend you have one whole layout which is holding your two small buttons which area must be expanded,so you MUST make another layout inside your main layout and put another button to your newly created layout so in that case with static method you can give touch delegate to 2 buttons at the same time.Now more deeply and step by step into code!
first you surely just find the view of your MAINLAYOUT and Button like this.(this layout will hold our first button)
ok we done finding the main layout and its button view which will hold everything its just our
onCreate()
displaying layout but you have to find in case to use it later.Ok what next?We create another RelativeLayout inside our main layout which width and height is on your taste(this newly created layout will hold our second button)ok we done finding views so we can now just copy and paste the code of our guy who firstly answered your question.Just copy that code inside your main activity.
Now how to use this method and make it work?here is how!
on your
onCreate()
method paste the next code snippetExplanation on what we did in this snipped.We took our created static method named
expandTouchArea()
and gave 3 arguments.1st argument-The layout which holds the button which area must be expanded
2nd argument - actual button to expand the area of it
3rd argument - the area in pixels of how much we want the button area to be expanded!
ENJOY!
我遇到了同样的问题:尝试为不同的 LinearLayouts 添加多个 TouchDelegates,在一个布局中将触摸事件分别路由到单独的 Switches。
有关详细信息,请参阅我提出的这个问题和我的回答。
我发现的是:一旦我分别用另一个
LinearLayout
包围LinearLayouts
,第二个(每隔一个连续的结束)TouchDelegate
开始按预期工作。因此,这可能有助于OP为他的问题创建一个可行的解决方案。
但对于它为什么会这样,我还没有一个令人满意的解释。
I had the same issue: Trying to add multiple
TouchDelegates
for differentLinearLayouts
that route touch events to separateSwitches
respectively, in one layout.For details please refer to this question asked by me and my answer.
What I found is: Once I enclose the
LinearLayouts
each by anotherLinearLayout
, respectively, the second (end every other successive)TouchDelegate
starts to work as expected.So this might help the OP to create a working solution to his problem.
I don't have a satisfying explanation on why it behaves like this, though.
我复制了 TouchDelegate 的代码并做了一些修改。现在它可以支持多个视图,无论这些视图是否有共同的父视图
}
像这样使用它
I copy the code of TouchDelegate and made some alter. Now it can support multi Views regardless of whether thoese views had common parents
}
use it like this
我从 Brendan Weinstein 上面列出的链接实现了一个简单的解决方案 - 与所有其他解决方案相比,静态方法非常干净整洁。填充对我来说根本不起作用。
我的用例是增加 2 个小按钮的触摸面积以改善用户体验。
我有一个
MyUserInterfaceManager
类,我在其中插入 youtube 视频< /a>;然后在 XML 中我有以下代码(每个图像按钮);
在我的片段的
onCreateView(...)
方法中,我调用了每个需要修改触摸区域的View
的方法(在绑定两个Views
之后) >!);这个解决方案意味着我可以明确地设计和查看布局文件中的触摸区域 - 必须确保我不会太靠近其他
View
触摸区域(与推荐的“计算和添加像素”方法相比)由谷歌和其他人提供)。I implemented a simple solution from the link that Brendan Weinstein listed above - the static method was incredibly clean and tidy compared to all other solutions. Padding for me simply doesnt work.
My use case was increasing the touch area of 2 small buttons to improve UX.
I have a
MyUserInterfaceManager
class, where i insert the static function from the youtube video;Then in XML i have the following code (per imagebutton);
The in the
onCreateView(...)
method of my fragment i called the method perView
that needs the touch area modified (after binding bothViews
!);This solution means i can explicitly design and see the touch area in layout files - a must have to ensure im not getting too close to other
View
touch areas (compared to the "calculate and add pixels" methods recommended by google and others).您可以使用复合模式向
View
添加多个TouchDelegate
。步骤:TouchDelegateComposite
(无论您将作为参数,它仅用于获取上下文)
TouchDelegates
并将它们添加到复合按照建议添加复合以查看此处(通过
view.post(new Runnable)
)You can use composite pattern to be able to add more than one
TouchDelegate
to theView
. Steps:TouchDelegateComposite
(no matter what view you'll pass as anargument, it's used just to get the Context)
TouchDelegates
and add them to compositeAdd composite to view as they recommend here (via
view.post(new Runnable)
)