7

誰かが私の構文を手伝ってくれますか?XMLですでに定義されているFrameLayoutにいくつかのビュー(カスタムビュー)を動的に追加しています。これらのカスタムビューは、異なるタイプまたは同じタイプです。画面にビューを追加することはできますが、ViewGroupから特定のビュー(同じタイプまたは異なるビュー)を削除できません。を持っているそれらのカスタムビューonTouch()

ここで私は問題に直面しています:トリガーすることができずlong click、常にかかりますtouch listener

ユーザーがビューを長押ししたときにビューを選択した場合、ここで2つのオプションを作成する必要があります

  1. 背景色を変更する
  2. ビューを削除します。

編集:提案によると、tao表示するタッチリスナーがない場合は、長押しされたビューのインデックスを取得できます。しかし、私は長押しと一緒にタッチリスナーを実装する必要があります...

これどうやってするの?

4

5 に答える 5

3

わかりました。問題は「ロングクリックでトリガーできない、常にタッチリスナーが必要」ですが、これだけでは不十分です。詳細が必要です:

  1. ロングクリック、親ビュー、または子ビューのどのビューを処理することになっていますか?
  2. ロングクリックの処理に使用したリスナー、android.view.View.setOnLongClickListenerまたはandroid.view.GestureDetector?

実は先週同じ仕事をしました。私の経験は次のとおりです。android.view.View.setOnLongClickListenerもandroid.view.GestureDetectorも使用せず、親ビューのロングクリックを自分で処理します。View.javaは良い例です。


編集:

手元にコンパイラがないので、長押しを自分で処理する擬似コードを入力するだけです。実際のコードの場合、View.javaが最良の答えを提供します。

まず、アクションを実装するためのランナブルが必要です

class CheckForLongPress implements Runnable {
    public void run() {
        if (getParent() != null) {
            // show toast
        }
    }
}

次に、onTouchEventを変更して長押しを検出します

boolean onTouchEvent(...) {
    switch (event.getAction()) {
        case MotionEvent.ACITON_DOWN:
            // post a delayed runnable to detecting long press action.
            // here mPendingCheckForLongPress is instance of CheckForLongPress
            postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout());
            ...
            break;

        case MotionEvent.ACTION_MOVE:
            // cancel long press action
            if (distance(event, lastMotionEvent) > mTouchSlop) {
                removeCallbacks(mPendingCheckForLongPress);
            }

            ...

            break;

        case MotionEvent.ACTION_UP:
            // cancel long press action
            removeCallbacks(mPendingCheckForLongPress);

            ...

            break;

もう一度編集:

以下は、疑似コードではなく実際のコードです。これは非常に単純で、View.onTouchEvent()で長押しを処理する方法を示しています。

public class ItemView extends View {

    public ItemView(Context context) {
        super(context);
    }   

    public ItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public ItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    Runnable mLongPressDetector = new Runnable() {
            public void run() {
                Toast.makeText(getContext(), "Hello long press", Toast.LENGTH_SHORT).show();
            }
        };

    MotionEvent mLastEvent;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        mLastEvent = MotionEvent.obtain(event);

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            postDelayed(mLongPressDetector, ViewConfiguration.getLongPressTimeout());
            break;

        case MotionEvent.ACTION_MOVE:
            final int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
            if (Math.abs(mLastEvent.getX() - event.getX()) > slop ||
                Math.abs(mLastEvent.getY() - event.getY()) > slop) {
                removeCallbacks(mLongPressDetector);
            }
            break;

        case MotionEvent.ACTION_UP:
            removeCallbacks(mLongPressDetector);
            break;

        }
        return true;
    }

}
于 2012-07-13T01:27:19.307 に答える
1

ここを見て:

http://developer.android.com/reference/android/view/View.html

getId()をintにするメソッドがあります。したがって、すべてのビューには一意の識別子があります。あなたはこれまでのビューにそれを使用することができます。

于 2012-07-09T05:17:58.023 に答える
1

ここで私の質問は、ユーザーがそのビューに触れたときに、ビューのグループから選択したビューをどのように識別することができるかです。

TwoPointsDraw私は&OnePointDrawがビューを拡張していると仮定します。

したがって、この場合にできることは、TwoPointsDrawのオブジェクトを作成した後です。一意のIDまたはタグをそれに割り当てます。

TwoPointsDraw drawView = new TwoPointsDraw(context);
drawView.setTag("unique identifier"); <-Must be object type
drawView.setId(unique id); <-must be integer type

また、特定のビューをクリックすると、を使用してそのIDを確認できます。

view.getTag()またview.getId()

スニペットは次のようになります

circle.setOnLongClickListener(new OnLongClickListener() {

    @Override
    public boolean onLongClick(View v) {
        Log.i("Long", v.getTag().toString());
        return false;
    }
});

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

于 2012-07-09T05:18:27.667 に答える
1

機能させるOnLongClickListenerには、onTouch 関数で長いクリックを検出したときに false を返す必要があります。

例えば:

GestureDetector で onLongClickListener にチャンスを与えるには、次のことを行う必要があります。

@Override
public boolean onDown(MotionEvent ev) {
    return false;
    // return super.onTouchEvent(ev);
}

さもないと:

ビューで関数を実装し、渡されたインスタンスsetOnLongClickListenerを保存します。onLongClickListener長いクリックが検出されるたびに、インスタンスのonLongClick関数を呼び出します。

于 2012-07-12T22:45:03.460 に答える