问题描述
|
我已经为此工作了一段时间。想法一开始很简单,我希望在SlidingDrawer手柄上有一个按钮,以允许用户查看特定于抽屉内容的设置。因此,我制作了一个侧面没有按钮的布局,并将其设置为手柄。抽屉拉得很好,但是不允许按下(手柄上的)按钮。每当我尝试单击事物时,该单击都被解释为手柄单击,并切换抽屉的状态。
有人知道发生了什么吗?
谢谢〜伊顿
解决方法
您可以使用布局XML的SlidingDrawer元素中的属性,禁止将单击句柄按钮的操作解释为\“ open \”。像这样:
<SlidingDrawer android:layout_width=\"fill_parent\"android:id=\"@+id/SlidingDrawer\" android:handle=\"@+id/slideHandleButton\"
android:content=\"@+id/txtHolder\" android:layout_height=\"fill_parent\"
android:orientation=\"horizontal\" android:allowSingleTap=\"false\">
只需使ѭ1,然后像通常那样为按钮实现一个单击处理程序即可。这将阻止它打开/关闭抽屉,但是您可能需要拦截按钮的事件才能使按钮执行您想要的操作。
,我将发布实现,以免给其他人带来麻烦。
基本上,您必须扩展SlidingDrawer类并处理onInterceptTouch事件,使其在句柄布局内的项目之上时通过。
假设您正在使用ViewGroup(例如,任何布局)作为句柄,并且其中的所有视图都是可单击的。
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SlidingDrawer;
public class ClickableSlidingDrawer extends SlidingDrawer {
private ViewGroup mHandleLayout;
private final Rect mHitRect = new Rect();
public ClickableSlidingDrawer(Context context,AttributeSet attrs,int defStyle) {
super(context,attrs,defStyle);
}
public ClickableSlidingDrawer(Context context,AttributeSet attrs) {
super(context,attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View handle = getHandle();
if (handle instanceof ViewGroup) {
mHandleLayout = (ViewGroup) handle;
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mHandleLayout != null) {
int childCount = mHandleLayout.getChildCount();
int handleClickX = (int)(event.getX() - mHandleLayout.getX());
int handleClickY = (int)(event.getY() - mHandleLayout.getY());
Rect hitRect = mHitRect;
for (int i=0;i<childCount;i++) {
View childView = mHandleLayout.getChildAt(i);
childView.getHitRect(hitRect);
if (hitRect.contains(handleClickX,handleClickY)) {
return false;
}
}
}
return super.onInterceptTouchEvent(event);
}
}
然后,在布局.xml中,仅使用<my.package.name.ClickableSlidingDrawer>
而不是<SlidingDrawer>
,我尝试了d4n3的实现,但是由于我的句柄包含一个嵌套在多个ѭ5中的按钮,因此我必须对其进行修改以使其起作用。
我的实现还假定您在句柄上使用ѭ5,但是子视图不必是可单击的。此外,还必须将“ 7”设置为要在句柄中单击的视图的“ click_intercepted \”。只有带有此特定标签集的子视图才会被考虑用于手柄内的点击。这样,您可以随意布置手柄,并且仍然可以对单击手柄中特定的View
(例如ѭ9appropriately)进行适当的操作。同样,通过此实现,您仍然可以拖动并单击手柄以切换其状态。
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SlidingDrawer;
public class ClickableSlidingDrawer extends SlidingDrawer
{
private static final String TAG_CLICK_INTERCEPTED = \"click_intercepted\";
private ViewGroup mHandleLayout;
private final Rect mHitRect = new Rect();
public ClickableSlidingDrawer(Context context,AttributeSet attrs)
{
super(context,attrs);
}
public ClickableSlidingDrawer(Context context,int defStyle)
{
super(context,defStyle);
}
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
View handle = getHandle();
if (handle instanceof ViewGroup)
{
mHandleLayout = (ViewGroup) handle;
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
if (mHandleLayout != null)
{
int clickX = (int) (event.getX() - mHandleLayout.getLeft());
int clickY = (int) (event.getY() - mHandleLayout.getTop());
if (isAnyClickableChildHit(mHandleLayout,clickX,clickY))
{
return false;
}
}
return super.onInterceptTouchEvent(event);
}
private boolean isAnyClickableChildHit(ViewGroup viewGroup,int clickX,int clickY)
{
for (int i = 0; i < viewGroup.getChildCount(); i++)
{
View childView = viewGroup.getChildAt(i);
if (TAG_CLICK_INTERCEPTED.equals(childView.getTag()))
{
childView.getHitRect(mHitRect);
if (mHitRect.contains(clickX,clickY))
{
return true;
}
}
if (childView instanceof ViewGroup && isAnyClickableChildHit((ViewGroup) childView,clickY))
{
return true;
}
}
return false;
}
}
,首先创建一个布局,并将其中的Handle内容放入其中(例如,您放入handle_content.xml)。
其次,用以下命令替换当前的手柄handle11ѭ:
<include android:id=\"@id/handle\"
android:layout=\"@layout/handle_content.xml\"/>
现在执行以下操作(我这样说是因为如果您执行以上操作,则以下内容可以正常工作)
这是我的实现:
package com.examples.my.views;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SlidingDrawer;
import com.examples.my.MainFragmentActivity;
public class MYSlidingDrawer extends SlidingDrawer {
private View button;
private int height;
private MainFragmentActivity activity;
public MYSlidingDrawer (Context context,attrs);
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
height = metrics.heightPixels;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
int left = button.getLeft();
int top = button.getTop();
int right = button.getRight();
int bottom = button.getBottom();
Rect rect = new Rect(left,top,right,bottom);
int x = (int) event.getX();
int y = (int) event.getY();
if (isOpened()) {
if (rect.contains(x,y)) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (activity != null)
{
//HERE DO YOUR WORK
// Like activity.tooglePlay();
}
}
return true;
}
} else {
y -= height;
if (rect.contains(x,Math.abs(y))) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (activity != null)
{
//HERE DO YOUR WORK
// Like activity.tooglePlay();
}
}
return true;
}
}
return super.onTouchEvent(event);
}
public void setButton(View button) {
this.button = button;
}
public void setActivity(MainFragmentActivity activity) {
this.activity = activity;
}
}
现在定义它,其中包括MYSlidingDrawer:
MYSlidingDrawer drawer = (MYSlidingDrawer) findViewById(R.id.drawer);
drawer.setActivity(this);
Button btn = (Button) findViewById(R.id.play_btn);//button inside your handle
drawer.setButton(btn);
希望对您有帮助。