9

私はしばらくこれに取り組んできました。アイデアは単純なものから始まりました。SlidingDrawer ハンドルにボタンを配置して、ドロワーのコンテンツに固有の設定をユーザーが表示できるようにしたかったのです。ということでボタンを横にずらしてレイアウトし、ハンドルにしました。引き出しはうまく引き出されましたが、(ハンドルの)ボタンを押すことができませんでした. 物をクリックしようとすると、クリックはハンドルのクリックとして解釈され、ドロワーの状態が切り替わります。

誰が何が起こっているのか知っていますか?

ありがとう〜エイドン

4

4 に答える 4

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

次に、レイアウト .xml で<my.package.name.ClickableSlidingDrawer>代わりに使用します<SlidingDrawer>

于 2011-12-08T17:27:18.603 に答える
13

d4n3 の実装を試してみましたが、私のハンドルには複数ViewGroupの にネストされたボタンが含まれているため、それを機能させるために変更する必要がありました。

私の実装では、ハンドルに を使用していることも想定していますViewGroupが、子ビューはクリック可能である必要はありません。また、ハンドルでクリック可能にしたいビューのtagclick_intercepted 」を設定する必要があります。この特定のタグ セットを持つ子ビューのみが、ハンドル内のクリックと見なされます。このようにして、ハンドルを好きなようにレイアウトし、ハンドル内の特定Viewの s (aButtonなど) をクリックすると適切に動作することができます。また、この実装では、ハンドルをドラッグおよびクリックして、その状態を切り替えることができます。

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;
    }
}
于 2012-03-22T13:59:05.523 に答える
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">

android:allowSingleTap="false"次に、通常のようにボタンのクリック ハンドラーを実装するだけです。これにより、ドロワーの開閉が停止しますが、ボタンのイベントをインターセプトして、やりたいことを実行させる必要がある場合があります。

于 2011-04-15T16:13:06.467 に答える
0

最初にレイアウトを作成し、その中にハンドル コンテンツを配置します (handle_content.xml に配置するとします)。

次に、現在のハンドルhandle を次のように置き換えます。

<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, AttributeSet attrs) {
        super(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);

これがお役に立てば幸いです。

于 2013-07-20T16:49:06.457 に答える