添加按钮到SlidingDrawer句柄?

aho*_*der 9 android onclick slidingdrawer

我一直在研究这个问题.想法开始很简单,我想在SlidingDrawer句柄上有一个按钮,允许用户查看特定于抽屉内容的设置.所以我做了一个布局,侧面有一个按钮,并将其设置为手柄.抽屉拉得很好,但是不允许按下按钮(在把手上).当我尝试单击该东西时,单击被解释为手柄单击,并切换抽屉的状态.

有谁知道发生了什么?

谢谢~Aedon

d4n*_*4n3 13

我将发布我的实施,以拯救他人的麻烦.

你基本上必须扩展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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的布局.xml中使用<my.package.name.ClickableSlidingDrawer>而不是<SlidingDrawer>


jac*_*b11 13

我尝试了d4n3的实现,但由于我的句柄包含一个嵌套在多个ViewGroups 中的按钮,我不得不修改它以使其工作.

我的实现还假设您使用了ViewGroup句柄,但子视图不必是可点击的.此外,您必须将要在按钮中单击的视图设置tag为" click_intercepted ".对于句柄内的点击,将仅考虑具有此特定标记集的子视图.这样,您可以随意布置手柄,并且仍然可以对手柄中特定Views(例如a Button)的点击进行适当的操作.此外,通过此实现,您仍然可以拖动并单击手柄以切换其状态.

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, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, 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, clickX, clickY))
            {
                return true;
            }
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)


koo*_*ng3 5

您可以使用布局XML中SlidingDrawer元素中的属性来抑制将句柄按钮上的单击解释为"打开"的操作.像这样:

<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">
Run Code Online (Sandbox Code Playgroud)

只需制作android:allowSingleTap="false"然后就像通常那样为按钮实现一个点击处理程序.这将阻止它打开/关闭抽屉,但您可能需要截取按钮的事件以使其按照您的要求执行操作.