web-dev-qa-db-ja.com

TabLayoutを無効にする

デザインライブラリで提供されている新しいクラスであるTabLayoutを使用しています。また、特定のケースでは、使用しているタブでタブを変更できないようにします。

ビューページャーでスワイプを無効にすることはできますが、タブをクリックしてもページの変更を無効にする方法がわかりません。

前もって感謝します。

45
MHogge

私は同じ問題を抱えていたので、次のコードでタブ上のタッチイベントを無効にして解決しました:

  LinearLayout tabStrip = ((LinearLayout)mTabLayout.getChildAt(0));
    for(int i = 0; i < tabStrip.getChildCount(); i++) {
        tabStrip.getChildAt(i).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });
    }
95
Michele

OnTouchイベントをオーバーライドすることなく、必要に応じてタブを再度有効にすることができる、もう少しシンプルな同様の回答を見つけました。

TabLayout tabLayout = (TabLayout)  mParentView.findViewById(R.id.my_tabs);

LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
tabStrip.setEnabled(false);
for(int i = 0; i < tabStrip.getChildCount(); i++) {
    tabStrip.getChildAt(i).setClickable(false);
}

また、タブを再度有効にする場合は、子要素のtabStrip.setEnabledおよびsetClickableをtrueに設定するだけです。

LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
tabStrip.setEnabled(true);
for(int i = 0; i < tabStrip.getChildCount(); i++) {
    tabStrip.getChildAt(i).setClickable(true);
}
36
pat8719

Pat8719の回答と非常によく似ていますが、タブを選択しないようにするにはタブを無効にするだけで十分です。

TabLayout tabLayout = (TabLayout)  mParentView.findViewById(R.id.my_tabs);
TabLayoutUtils.enableTabs( tabLayout, false );

TabLayoutUtilsクラス

public class TabLayoutUtils {

    public static void enableTabs(TabLayout tabLayout, Boolean enable){
        ViewGroup viewGroup = getTabViewGroup(tabLayout);
        if (viewGroup != null)
            for (int childIndex = 0; childIndex < viewGroup.getChildCount(); childIndex++)
            {
                View tabView = viewGroup.getChildAt(childIndex);
                if ( tabView != null)
                    tabView.setEnabled(enable);
            }
    }

    public static View getTabView(TabLayout tabLayout, int position){
        View tabView = null;
        ViewGroup viewGroup = getTabViewGroup(tabLayout);
        if (viewGroup != null && viewGroup.getChildCount() > position)
            tabView = viewGroup.getChildAt(position);

        return tabView;
    }

    private static ViewGroup getTabViewGroup(TabLayout tabLayout){
        ViewGroup viewGroup = null;

        if (tabLayout != null && tabLayout.getChildCount() > 0 ) {
            View view = tabLayout.getChildAt(0);
            if (view != null && view instanceof ViewGroup)
                viewGroup = (ViewGroup) view;
        }
        return viewGroup;
    }

}
17
grantnz

あなたが使用できる良いトリック:

次のようなクリックから保護するビューをカバーするフレームレイアウトを作成します。

<FrameLayout
    Android:clickable="true"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"/>

このコードは、ビューの上に空の/透明なビューを作成します。 Android:clickable = "true"はクリックをインターセプトし、クリックがビューを通過しないようにします。

このハックはおそらく最適化できますが、複数のビューを同時に保護するための数行のコードです!

10
Tobliug

私にとっての作業方法は次のとおりです。

bool condition = ...
foreach (var view in _tabLayout.Touchables)
    view.Clickable = condition;

getTouchables() 呼び出しはAPI 1からサポートされているため、これは100%安全です。レイアウトなどを手動でトラバースする必要はありません。私はそれが受け入れられた答えよりもはるかに簡単であると考えていますが、すべてのタブがクリック不可とマークされる必要がある場合のみです。

追伸:Xamarinを使用しているので、例はC#にありますが、Javaに戻すのはかなり簡単です。楽しい! =)

Kotlinの例:

tabLayout.touchables.forEach { it.isClickable = false }

Javaの例:

for (View v: tabLayout.getTouchables())
    v.setClickable(false);
7
Vladislav Rishe

タブにカスタムビューを使用している場合、ViewGroupsを調べたくない場合は、View#getParent()を使用してタブのビューへの参照を取得できます。

注:親の代わりにカスタムビュー自体を使用すると、マージンがあるため、ユーザーが空のスペースをクリックしてタブを変更できるため、機能しない場合があります。

View tabView = (View) tab.getCustomView().getParent();

tabView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});

//or

tabView.setEnabled(false);

OnTouchListenerの方法とsetEnabled()の方法は異なることを行いますが、効果は同じです。私はワンライナーを好む。

繰り返しますが、カスタムビューを使用する場合にのみ機能します。そうしないと、getParent()呼び出しによりNullPointerExceptionが発生します。

4
Jacob Muchow

この優れたソリューションに基づいて、誰かがKotlinでそれを必要とする場合:

  val tabStrip = mTabLayout.getChildAt(0) as LinearLayout
    for (i in 0..tabStrip.childCount) {
        tabStrip.getChildAt(i).setOnTouchListener(object : View.OnTouchListener{
            override fun onTouch(p0: View?, p1: MotionEvent?): Boolean {
                return true
            }
        })
    }

または、ラムダを使用したよりエレガントなソリューション

mTabLayout.setOnTouchListener {v: View, m: MotionEvent ->
        true
 }
0
BMU

ここで私の答えを確認してください TabLayoutでタブを無効にする

ループタブでこの機能を使用して、すべてのタブを無効にすることができます

0

TabLayoutクラスを拡張し、すべてのタッチイベントをインターセプトすることで、子クリックを回避することもできます。

class NonTouchableTabLayout : TabLayout {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return true
    }
}

再度クリックを有効にする場合は、onInterceptTouchEventメソッドでfalseを返すだけです。

0
Cedulio Cezar