2014-01-14 6 views
15

私はRelative Layoutを使用しており、TextViewsなどで多くのボタンを使用しています。何らかのイベントが発生しない限り、すべてをclickableにしないでください。Androidレイアウトすべての子供をクリックできないようにする

RelativeLayout.setClickable(false);を設定しようとしましたが、レイアウト内のすべての要素がclickableです。

それぞれの子要素を設定するのはclickableではありませんが、レイアウト内にボタンのような子要素がたくさんあるので、適切な方法ではありません。

ここで私の質問はです。setClickable(false);layoutに設定するにはどうすればいいですか?

+1

ここで編集で_heck_何が起こったのですか? –

答えて

20

クリックと言うときは、実際にはタッチを意味しますか?タッチイベントは要素ごとに行われます。彼らは最初にトップレベルに送られます。トップレベルには、それが処理されたかどうかが表示され、そうでなければ、ビューの各子供に表示されます。

タッチイベントが作成されると、チェーン内のonTouchのビューのメソッドが呼び出されます。これらのいずれかがtrueを返す場合(trueが「これを処理しました!」という意味です)、子プロセスは終了します。

YOUR_RELATIVE_LAYOUT.setOnTouchListener(new OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // ignore all touch events 
     return true; 
    } 
}); 

これは、すべてのタッチ相対的なレイアウトで発生したイベント(とのすべてを無視します:あなたは、単にこのように、onTouchListenerを設定する必要があり、そのすべての子のためのあなたのrelativelayoutブロックタッチとクリックを作るために

その子供たち)は、単純なタッチダウンを含むイベント(クリックと呼ばれる)をリリースします。

+0

私のために働いた:)ありがとう – Aakanksha

10

次の機能を使用すると、すべての子ビューを見つけてクリックをキャンセルできます。

public void setClickable(View view) { 
    if (view != null) { 
     view.setClickable(false); 
     if (view instanceof ViewGroup) { 
      ViewGroup vg = ((ViewGroup) view); 
      for (int i = 0; i < vg.getChildCount(); i++) { 
       setClickable(vg.getChildAt(i)); 
      } 
     } 
    } 
} 
1

あなたがその特定の機能を実行したときのレイアウトでいくつかの項目のクリックを実行しようとしているので、

  • あなたは、静的なブール値を作成し、ブール
  • のような静的なフラグを保つことができますグローバルに指定し、falseと宣言したら、特定の機能が実行されたらtrueに変更します。
  • したがって、すべてのonclick関数では、trueの場合にこのフラグをチェックして、必要関数を実行します。
0

は、あなたは、あなたの相対的なレイアウト内のすべてのビューを無効にするためのコードを記述し、onCreate()でこのメソッドを呼び出すことが可能な一般的な方法を作ることができ、その後、あなたはあなたのイベントで、レイアウト内のあなたの特定のビューを有効にすることができます。

0

ボタンをループし、setClickable関数を使用してfalse値を渡します。 次に、otでループが発生し、setClickableがtrueになると、

9

これを実現する別の方法が見つかりました。あなたは以下のようにRelativeLayoutでトップのすべての兄弟のビュー上のブロッキングのLinearLayoutを作成することがあります。

<RelativeLayout 
    android:id="@+id/rl_parent" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <!-- the children views begins --> 
    ... 
    <!-- the children views ends --> 

    <LinearLayout 
     android:id="@+id/ll_mask" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@android:color/transparent" 
     android:clickable="true" 
     android:orientation="horizontal" 
     android:visibility="visible"/> 

</RelativeLayout> 

後で、あることを子どもたちの意見を許可するようにGONEへのLinearLayoutの表示を切り替えることが再びクリッカブル:

mMask.setVisibility(View.VISIBLE); // blocks children 
mMask.setVisibility(View.GONE); // children clickable 
+0

良い答え。子どもが多す​​ぎるレイアウトではパフォーマンス上の問題はありません。 – slhddn

+0

これまで最高の答え。 –

+0

私は使ってみたいとは思っていませんでしたが、終わりには時間を節約しました。ありがとう、+1。 – alchemist

0

Butterknifeライブラリを使用すると、ビューをグループ化することができ、グループで機能を実行できます。 http://jakewharton.github.io/butterknife/を参照してください、

@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name }) 
List<EditText> nameViews; 

適用方法は、あなたが一度にリスト内のすべてのビューに基づいて行動することができます。

ButterKnife.apply(nameViews, DISABLE); 
ButterKnife.apply(nameViews, ENABLED, false); 

アクションおよびセッターインターフェイスで簡単な動作を指定できます。例えばのために

static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() { 
    @Override public void apply(View view, int index) { 
    view.setEnabled(false); 
    } 
}; 

static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() { 
    @Override public void set(View view, Boolean value, int index) { 
    view.setEnabled(value); 
    } 
}; 

。textviewsがグループ化されている場合は、ViewGroupの子どもたちがイベントに触れ応答しないようにしたいが、あなたはViewGroup自体が応答する場合、あなたは

static final ButterKnife.Setter<TextView, Boolean> ENABLED = new ButterKnife.Setter<TextView, Boolean>() { 
     @Override public void set(TextView view, Boolean value, int index) { 
      view.setClickable(value); 
      view.setLongClickable(value); 
      if(value){ 
       view.setTextColor(color); 
      } else { 
       view.setTextColor(color); 
      } 
     } 
    }; 
1

を行うことができますたとえば、独自のViewGroupサブクラスを作成し、onInterruptTouchEvent()を上書きし、常にtrueを返すことができます。子供がそれらを見る前にすべてのタッチイベントを傍受し、あなたのカスタムViewGroupをタッチイベントに応答したままにします。

代わりRelativeLayoutの、あなたがあなた自身のサブクラス使用することができますので、:

public class ControlFreakRelativeLayout extends RelativeLayout { 
    private boolean mWithholdTouchEventsFromChildren; 

    // Constructors omitted for sake of brevity 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     return mWithholdTouchEventsFromChildren || super.onInterceptTouchEvent(ev); 
    } 

    public void setWithholdTouchEventsFromChildren(boolean withholdTouchEventsFromChildren) { 
     mWithholdTouchEventsFromChildren = withholdTouchEventsFromChildren; 
    } 
} 
+0

偉大な、私の日を救う –

1

をそれを行うには非常にシンプルでフルプルーフな方法は、サブクラスを作成し、onInterceptTouchEventを上書きすることです:

public class MyRelativeLayout extends RelativeLayout { 
    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     // true if you do not want the children to be clickable. 
     return mShouldInterceptAllTouch; 
    } 
} 

子どものメソッドを呼び出す必要はありません。

myRelativeLayoutオブジェクトでは、引き続きsetOnClickListenerと電話することができます。また、XMLでクラスを使用しているかのように使用することができますRelativeLayout

関連する問題