4

私が達成したいのは、1 つを除いて ActionBar のすべての項目を無効にすることです。ListNavigationから、いくつか、1つ、および1つのカスタムActionBarがあります。スピナーは次のような理由で作成されます:MenuTextViewsButtonSpinnerbar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

    SpinnerAdapter spinnerAdapter = new ArrayAdapter<String>(this.getActivity(), R.layout.action_bar_spinner, names);
    // "listener" for spinner
    bar.setListNavigationCallbacks(spinnerAdapter, new OnNavigationListener() {
        @Override
        public boolean onNavigationItemSelected(int position, long itemId) {
            // do some stuff

            return true;
        }
    });

を無効にしてSpinner、非アクティブにしますが、無効にする前に最後の項目を選択したまま表示します。要するにbar.getNavigationSpinner.setEnabled(false)、存在する場合のようなものが必要です。質問: 何らかの回避策はありますか? そうでない場合、全体を無効にする方法はありますが、ActionBar表示したままにしますか?

注:フラグメントで実現したい。

4

3 に答える 3

6

Spinnerはい、 で使用されているリスト ナビゲーションを無効にすることができActionBarます。しかし、これは簡単な解決策ではなく、ハックです。SpinnerActionBar は、ビューへの直接アクセスを提供しません。残念ながら、Spinnerは ID なしのプライベート コードで作成されます。

Spinnerでは、インスタンスにアクセスするにはどうすればよいでしょうか。1 つの解決策は、Java リフレクション API を介してアクセスすることですが、それはお勧めしません。

より良い解決策は、現在の のルート ビューを取得し、そのActivity子ビュー (アクション バーとそのすべてのビューがビュー階層に存在する) をトラバースし、適切な を見つけることSpinnerです。イン アクション バーはおそらく自分で作成していない唯一のものであるため、Spinner他のバーと区別できるはずです。

ルートの取得については、この SO questionViewで説明されています。

トラバーサルはかなり単純ですが、ActionBarSherlockIcsSpinnerを使用している場合は、代わりにSpinner(IcsSpinnerから拡張されていない)を探す必要があることに注意してくださいSpinner

private View findActionBarSpinner() {
    View rootView = findViewById(android.R.id.content).getRootView();
    List<View> spinners = traverseViewChildren( (ViewGroup) rootView );
    return findListNavigationSpinner(spinners); // implement according to your layouts
}

private List<View> traverseViewChildren(ViewGroup parent) {
    List<View> spinners = new ArrayList<View>();
    for (int i = 0; i < parent.getChildCount(); i++) {
        View child = parent.getChildAt(i);
        if (child instanceof Spinner) {
            spinners.add( child );
        } else if (child instanceof IcsSpinner) { // add this if you are using ActionBarSherlock
            spinners.add( child );
        } else if (child instanceof ViewGroup) {
            spinners.addAll( traverseViewChildren( (ViewGroup) child ) );
        }
    }
    return spinners;
}

この関数findListNavigationSpinnerは、他のスピナーを区別できるように実装する必要があります。何も (またはそれから派生したビュー) を使用していない場合Spinner、返されるリストには項目が 1 つだけ含まれている必要があります。

上記のコードは、 で を取得する方法を説明してSpinnerActivityます。当然、Spinner内で fromを無効にしても問題ありませんFragment。フラグメントにはそのアクティビティへの参照があるため、アクティビティは何らかのインターフェイスを介してコードをフラグメントに公開できます。

于 2012-11-12T23:45:06.997 に答える
1

上記のコードは、Action Bar compat (v7 サポート ライブラリ)では機能しません。このサポート ライブラリを使用してアプリ (API 2.2) のアクション バー スピナーを有効/無効にする必要がありましたが、SpinnerICS代わりにクラスの名前がSpinner.

完全なパッケージ名は

android.support.v7.internal.widget.SpinnerICS

このクラスは表示されず、コードにインポートできないため、使用できません:

if (child instanceof SpinnerICS) ...

最後に、を使用して問題を解決しgetClass().getNameました。したがって、Action Bar 互換サポート ライブラリ (v7) を使用してスピナーを有効/無効にするコードは次のようになります。

private List<View> traverseViewChildren(ViewGroup parent) {
    List<View> spinners = new ArrayList<View>();
    for (int i = 0; i < parent.getChildCount(); i++) {
        View child = parent.getChildAt(i);

        String className = child.getClass().getName();
        if (child instanceof Spinner || className.equals("android.support.v7.internal.widget.SpinnerICS")) {
            spinners.add( child );
        } else if (child instanceof ViewGroup) {
            spinners.addAll( traverseViewChildren( (ViewGroup) child ) );
        }
    }
    return spinners;
}

また、findListNavigationSpinner メソッドを修正して、スピナー リストに防止する要素があるかどうかを確認しましたArrayIndexOutOfBoundsException。私のアプリ (アクション バー コンパット) にはスピナーが 1 つしかないため、コードは次のとおりです (複数のスピナーがある場合は、それを調整する必要があります)。

private View findListNavigationSpinner(List<View> spinners) {
    // We only have one spinner in the app
    View result = null;
    if (spinners != null && spinners.size() > 0) {
         result = spinners.get(0);
    }
    return result;
}
于 2013-10-31T10:25:44.247 に答える