49

Android documentationによると、Material Design スタイルは Spinner ウィジェットでサポートされています。

そこで、アプリでツールバーの上に配置して使用することにしました。

レイアウト/アクティビティベース.xml

<android.support.v7.widget.Toolbar
    android:id="@+id/my_awesome_toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="5dp"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
 </android.support.v7.widget.Toolbar>

活動テーマ

<style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/omni_primary_color</item>
    <item name="colorPrimaryDark">@color/omni_primary_color_dark</item>
    <item name="colorAccent">@color/omni_accent_color</item>
</style>

BaseActivity.java

public class BaseActivity extends ActionBarActivity {

    @InjectView(R.id.my_awesome_toolbar)
    Toolbar mToolbar;

    @InjectView(R.id.spinner)
    Spinner spinner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base);
        ButterKnife.inject(this);
        //setup toolbar
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        mToolbar.setNavigationIcon(R.drawable.ic_action_navigation_menu);
          
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mToolbar.getContext(),
                R.array.planets_array, R.layout.support_simple_spinner_dropdown_item);
        adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
    }
}

Lollipop スピナーとドロップダウンでは問題なく見えますが、ドロップダウンの背景色は白のメニュー ドロップダウンと比較して黒です。app:popupTheme="@style/ThemeOverlay.AppCompat.Light"それはスピナーには伝わらないと思います。

アンドロイド 5.0

ここに画像の説明を入力 ここに画像の説明を入力

Android 4.x の大きな問題は、ドロップダウンの背景色が白 (popupTheme が伝播したか?) で、スピナーの横のアイコンが黒であるということです。

アンドロイド 4.4

ここに画像の説明を入力

Android 5 と 4 の両方で動作するように、XML で適切に設定するか、コードに実装するにはどうすればよいですか? 理想的には、Android 5 のように見えますが、白いスピナー ドロップダウン (設定メニュー ドロップダウンのような) が必要です。

アップデート

colorControlNormalプロパティの設定がスピナーのフィルター アイコンに影響することに気付きました。誰かが(他のコンテンツコントロールを変更せずに)Spinnerでそれを利用する方法を見つけた場合、その発見と@Svenの回答を組み合わせたソリューションが得られます。

アップデート

次の変更により、スピナーのテキストとポップアップの色の問題が修正されます。したがって、最終的な解決策の唯一の問題はフィルター アイコンです。

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(),
                R.array.planets_array, R.layout.support_simple_spinner_dropdown_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

アップデート

フィルター アイコンは、実際にandroid:backgroundはスピナーの指定の一部であり、透明であることがわかりました。独自の背景を提供すると修正されます。

<item name="android:background">?android:selectableItemBackground</item>

謎解き!

パズルの最後のピースは、Android 5 の黒い背景と白いテキストのポップアップですが、カスタム レイアウトで解決できると思います。誰も完全な回答を提供しない場合は、私が自分で回答し、承認済みとしてマークします。

4

15 に答える 15

65

これが遅れていることはわかっていますが、この問題に遭遇したときにこの質問に出くわし、Google I/O 2014 アプリのBrowseSessionsActivityで解決策を見つけて適応させました。

レイアウト

toolbar_spinner.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Spinner
        android:id="@+id/toolbar_spinner"
        style="@style/Widget.MyApp.HeaderBar.Spinner"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"/>

</LinearLayout>

toolbar_spinner_item_actionbar.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@android:id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawablePadding="8dp"
        android:drawableRight="@drawable/spinner_triangle"
        android:fontFamily="sans-serif"
        android:paddingLeft="16dp"
        android:paddingRight="4dp"
        android:textColor="#ffffffff"
        android:textSize="18dp"
        android:textStyle="bold"/>

</LinearLayout>

spinner_triangleドローアブルはここにあります

toolbar_spinner_item_dropdown.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:drawablePadding="8dp"
        android:gravity="center_vertical|start"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#ff333333"
        android:textSize="16sp"/>
        
</LinearLayout>

スタイル

toolbar_spinner.xml次のスタイルを使用します。

<style name="Widget.MyApp.HeaderBar.Spinner" parent="Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
        <item name="android:background">?android:selectableItemBackground</item>
        <item name="android:dropDownSelector">?android:selectableItemBackground</item>
        <item name="android:divider">@null</item>
        <item name="android:overlapAnchor">true</item>
</style>

アダプタ

このアダプターは、独自のニーズに合わせて変更する必要があります。getTitle()スピナーに表示される各アイテムのテキストを返します。

private class YourObjectSpinnerAdapter extends BaseAdapter {
    private List<YourObject> mItems = new ArrayList<>();

    public void clear() {
        mItems.clear();
    }

    public void addItem(YourObject yourObject) {
        mItems.add(yourObject);
    }

    public void addItems(List<YourObject> yourObjectList) {
        mItems.addAll(yourObjectList);
    }

    @Override
    public int getCount() {
        return mItems.size();
    }

    @Override
    public Object getItem(int position) {
        return mItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getDropDownView(int position, View view, ViewGroup parent) {
        if (view == null || !view.getTag().toString().equals("DROPDOWN")) {
            view = getLayoutInflater().inflate(R.layout.toolbar_spinner_item_dropdown, parent, false);
            view.setTag("DROPDOWN");
        }

        TextView textView = (TextView) view.findViewById(android.R.id.text1);
        textView.setText(getTitle(position));

        return view;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        if (view == null || !view.getTag().toString().equals("NON_DROPDOWN")) {
            view = getLayoutInflater().inflate(R.layout.
                    toolbar_spinner_item_actionbar, parent, false);
            view.setTag("NON_DROPDOWN");
        }
        TextView textView = (TextView) view.findViewById(android.R.id.text1);
        textView.setText(getTitle(position));
        return view;
    }

    private String getTitle(int position) {
        return position >= 0 && position < mItems.size() ? mItems.get(position).title : "";
    }
}

ツールバーにスピナーを追加する

Toolbar toolbar = getActionBarToolbar();

View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.toolbar_spinner,
        toolbar, false);
ActionBar.LayoutParams lp = new ActionBar.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
toolbar.addView(spinnerContainer, lp);

YourObjectSpinnerAdapter spinnerAdapter = new YourObjectSpinnerAdapter();
spinnerAdapter.addItems(getMyObjectSpinnerData());

Spinner spinner = (Spinner) spinnerContainer.findViewById(R.id.toolbar_spinner);
spinner.setAdapter(spinnerAdapter);

結果

マテリアルスピナー

キットカットスピナー

于 2015-01-02T19:52:01.543 に答える
7

Spinner を Xml に実装しないでください

final ArrayAdapter spinnerAdapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(),
            R.array.main_navigation_list, R.layout.spinner_text);
    spinnerAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
    mNavigationTags = getResources().getStringArray(R.array.main_navigation_list);


    mNavigationSpinner = new Spinner(getSupportActionBar().getThemedContext());
    mNavigationSpinner.setAdapter(spinnerAdapter);

    mNavigationSpinner.setOnItemSelectedListener(this);
    mToolbar.addView(mNavigationSpinner);

このようにして、スピナーの横にあるアイコンが白になります

于 2014-12-05T06:40:20.197 に答える
6

下手な英語でごめんなさい。:)ツールバーでスピナーを直接作成する方が良いと思います。

これが私のフラグメントの例です。

public class Testfragment1 extends Fragment {

    Toolbar mToolbar;
    Spinner mSpinner;
    .....

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        .......                  
        mToolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
        //you can also set the style with the constructor
        mSpinner = new Spinner(getActivity());
        String[] frags = new String[]{
                "category1",
                "category2",
                "category3",
        };
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,frags);
        mSpinner.setAdapter(arrayAdapter);
        mToolbar.addView(mSpinner);
        return inflater.inflate(R.layout.fragment_testfragment1, container, false);
    }

    .........

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mToolbar != null && mSpinner != null) {
            mToolbar.removeView(mSpinner);
        }
    }
}

それは私の android-4.1-device: android-4.1-spinnerでうまく見えます

于 2014-11-09T13:14:59.667 に答える
3

完全ではない単純な方法ですが、4.x と 5.0 の両方で十分に統一されています。

画像

レイアウト ファイルからを削除し、<Spinner>プログラムで追加しました。これにより、白い三角形が正しく表示されるようになりました。

また、appcompat の必要な色を使用して、ドロップダウン アイテムのレイアウトも作成しました。

layout/spinner_dropdown_item.xml に注意してください。android:background="@color/primaryColor"

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@android:id/text1"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:textAppearance="?android:attr/textAppearanceListItemSmall"
      android:gravity="center_vertical"
      android:paddingLeft="12dp"
      android:paddingRight="12dp"
      android:background="@color/primaryColor"
      android:minHeight="?android:attr/listPreferredItemHeightSmall" />

そして活動では:

    SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(getApplicationContext(), R.array.your_array, R.layout.spinner_dropdown_item);
    Spinner navigationSpinner = new Spinner(getSupportActionBar().getThemedContext());
    navigationSpinner.setAdapter(spinnerAdapter);
    toolbar.addView(navigationSpinner, 0);

これは完全ではなく、アイテムをクリックしても強調表示されませんが、将来の appcompat ライブラリがこれらの問題を修正するのを待つ間は十分です (とにかく期待しています)。

于 2015-03-01T13:08:25.133 に答える
1

これができませんか?

スピナー アイテムのカスタム xml ファイル: your_spinner.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView  
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textColor="#000"         
    android:background="#FFF"
    />

これを使用して、スピナー アイテムを表示します。

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.your_spinner,list);

次に、ドロップダウン リソースを削除します。

于 2014-11-12T21:09:16.107 に答える
0

スピナーを使用するとクラッシュしました(Android 2.3.3 - 2.3.7)。

だから私はTintSpinnerを使用しようとしていますが、クラッシュしていません。オプションの解決策として自分自身を試してください

 <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.internal.widget.TintSpinner
            android:id="@+id/toolbar_spinner"
            style="@style/HeaderBar.Spinner"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>
    </LinearLayout>

以下のコードを使用して、ツールバーをキャストします

 View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.toolbar_spinner, toolbarTop, false);
        ActionBar.LayoutParams lp = new ActionBar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
        toolbarTop.addView(spinnerContainer, lp);

        ToolBarSpinnerAdapter spinnerAdapter = new ToolBarSpinnerAdapter(getLayoutInflater());
        String[] items = getResources().getStringArray(R.array.action_dropdown);
        spinnerAdapter.addItems(items);

        TintSpinner mNavigationSpinner = (TintSpinner) spinnerContainer.findViewById(R.id.toolbar_spinner);
        mNavigationSpinner.setAdapter(spinnerAdapter);
于 2015-02-05T14:37:49.157 に答える
0

バージョン 21 と 23 の新しい値を作成し、スピナー スタイルandroid:dropDownVerticalOffsetに新しい属性を追加して、デフォルトのスタイル ファイルから削除することで解決しました。(私の場合はツールバーとは関係ありません)通常のスピナー用です。

このスタイルをフォルダ 23 と 21 に追加します

<style name="spinner_style">
    <item name="android:background">@drawable/background_spinner</item>
    <item name="android:dropDownVerticalOffset">30dip</item>
</style>

すべてのバージョンで完全に機能しています。これがうまくいくことを願っています!

于 2016-03-27T07:59:46.133 に答える
0

これを拾うために、私は同様の問題を抱えていました。私の主な問題は、ツールバーのテキストが通常のタイトルのサイズよりも小さく、色が間違っていたことです。スクリーンショットはこちらhttp://s27.postimg.org/v24x1aw43/Screen_Shot_2015_01_11_at_13_36_04.png

ドロップダウン メニューは問題ありませんでしたが、それもカスタマイズします。

また、この修正は主に@Daniel Bの修正に基づいていることを明確にしますが、何も壊れていないと言える限り、カスタムアダプターは必要ありませんが、保証はしません!

  1. 通常のスピナー項目を XML レイアウト ファイル (ツールバー内) に追加します。
<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="5dp"
        android:minHeight="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:theme="@style/GalaxyZooThemeToolbarDarkOverflow"
        app:popupTheme="@style/Theme.AppCompat"
        >

    <Spinner
        android:id="@+id/spinner_nav"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


    </android.support.v7.widget.Toolbar>
  1. 新しいレイアウト ファイル toolbar_spinner_item_actionbar.xml を作成します (これは、ツールバーのスピナーに表示されるものになります)
<?xml version="1.0" encoding="utf-8"?>

<TextView
    android:id="@android:id/text1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawablePadding="20dp"
    android:fontFamily="sans-serif"
    android:paddingLeft="@dimen/abc_action_bar_default_padding_material"
    android:paddingRight="4dp"
    android:textColor="@color/colorDark"
    android:textSize="@dimen/abc_text_size_title_material_toolbar"
    xmlns:android="http://schemas.android.com/apk/res/android"/>

    <!-- android:drawableRight="@drawable/spinner_triangle" -->
  1. スピナーのアダプターはほとんど同じままですが、レイアウトを標準の android.R.layout.simple_spinner_dropdown_item から R.layout.toolbar_spinner_item_actionbar に切り替えます。これにより、ツールバーのテキストにカスタムの外観が適用されます。

この例では、adapter.setDropDownViewResource を android.R.layout.simple_spinner_dropdown_item に設定しました。これにより、ドロップダウン リストの標準テーマのデフォルトが適用され、満足しています。

ArrayAdapter<String> set1Adapter = new ArrayAdapter<String>(RoutineDetailsActivity.this, R.layout.toolbar_spinner_item_actionbar, set1Actual);
        set1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        mWeekSpinner.setAdapter(set1Adapter);

基本的には以上です。結果はこちら [担当者が少なすぎるため、画像を添付したり、別のリンクを追加したりできません! コメントに追加します] . ここで終了することもできますが、ドロップダウン矢印の色を変更したい場合があります。

技術的には、これは私のアプリの正しい色合いですが、私の原色は既にツールバーの色であるため、矢印をカスタマイズすることは理にかなっています.

カスタム矢印ドローアブルのセットアップ

  1. このライン ドローアブル ライン 'android:drawableRight="@drawable/spinner_triangle' を以前に作成した toolbar_spinner_item_actionbar.xml に追加します。これは任意の画像である可能性があります。現時点では、Daniel B の白い矢印リソースをhttps://raw.githubusercontent で使用できます。 com/google/iosched/master/android/src/main/res/drawable-xxhdpi/spinner_triangle.png .

これを実行すると、白い矢印とテーマのデフォルトの 2 つの矢印が表示されます。これを解決するには、以下のスタイルを追加します。繰り返しますが、これは Daniel B のコードから引き出されたもので、おそらく省略されている可能性がありますが、今のところは機能します....

    <style name="Widget.MyApp.HeaderBar.Spinner" parent="Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
        <item name="android:background">?android:selectableItemBackground</item>
        <item name="android:dropDownSelector">?android:selectableItemBackground</item>
        <item name="android:divider">@null</item>
        <item name="android:overlapAnchor">true</item>
    </style>
  1. 作成したスタイルをスピナーに適用...
<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="5dp"
        android:minHeight="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:theme="@style/GalaxyZooThemeToolbarDarkOverflow"
        app:popupTheme="@style/Theme.AppCompat"
        >

    <Spinner
        android:id="@+id/spinner_nav"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Widget.MyApp.HeaderBar.Spinner"/>


    </android.support.v7.widget.Toolbar>

結果は次のようになります [ここでも添付またはリンクできません。コメントに追加します]。パディングは、以前のファイル設定から設定できます。私の場合、矢印をアイコンに合わせて変更する必要があります。

それが何らかの意味を成すことを願っています。

于 2015-01-11T14:35:14.787 に答える
0

この問題で何時間も無駄にしました。私が知る限り、上記のソリューションはすべて、タッチ状態などの基本的な詳細を再実装するために、appcompat スタイル コードの大きなチャンクをコピー アンド ペーストする必要があります。

ネイティブのような動作を得る比較的簡単な方法は、プログラムでビューをインフレートして、正しいテーマを確実に取得することです。次に例を示します。

// Activity has context with 'Theme.AppCompat.Light.NoActionBar'
spinner = new AppCompatSpinner(getActivity());
toolbar.addView(spinner);

三角形を ではなく白にするためにcolorControlNormal、ColorStateList の色合いを背景に適用しました。

ViewCompat.setBackgroundTintList(spinner, resources.getColorStateList(R.drawable.bg_toolbar_spinner)

bg_toolbar_spinner.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/accent" android:state_pressed="true"/>
    <item android:color="@android:color/white"/>
</selector>
于 2015-07-17T10:02:29.900 に答える