androidのSpinnerのDropDownListの背景を透過にする

前回Spinnreの文字色を変える方法を作成してみましたが、ふと思いついて背景を透過にすることができたので書いてみます。
ググってもそれらしいコードが見つからず、あきらめてダイアログか何かで代用しようかと思っていたのですが、どうにかなりました。

注意API 14 (android4.0) 以上では正常動作しません。
こちらをご参照ください。

TRY1

Eclipseを使用しました。android 2.2(APIレベル8)です。
まずIntentItemArrayAdapter:getDropDownView内のView convertViewの設定を変更してみました。
convertView.setBackgroundColor(Color.parseColor("#AAFFFFFF"));
という感じにしてみましたが、色は変えられても透明にはなりませんでした。
どうやら背景が透明ではないようです。
ViewGroup parentの設定を変更しても同様でした。
parent.getParent()を変更するとうまくいきました。
((View) parent.getParent()).setBackgroundColor(Color.parseColor("#AAFFFFFF"));
実行時のスナップショットです。
ただ、これだと枠線がなくなってしまってちょっとかっこ悪いです。


TRY2

枠線のXMLファイルを作成してそれを適用することにしました。
list_border.xml を作成して drawableに置きます
((View) parent.getParent()).setBackgroundDrawable(getResources().getDrawable(R.drawable.list_border));
としてみたらこのようになりました。
今回は白ですが、緑とか青っぽい色にするとかっこいいかもしれません。
スピナーにも同じ枠線ファイルを適用しています。▼マークが無くなるのでスピナーと分りづらいかも知れません。
それらしく見せるには別のファイル作成が必要でしょう。




コードは以下の通りです。
backimage.xmlは透過を分りやすくするために背景にドロイド君をタイル表示するのに使用しています。
前回と違う部分を赤で表示しています。XMLが増えた以外はほとんど同じです。


main.xml layoutに置きます
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/backimage"
    android:orientation="vertical" >

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

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

</LinearLayout>




list_border.xml drawableに置きます
<?xml version="1.0" encoding="utf-8" ?>
<shape  xmlns:android="http://schemas.android.com/apk/res/android"
android:shape ="rectangle">
<corners android:radius="5dip" />
<solid android:color="#AAFFFFFF"/> 
<padding
android:top="10dip"
android:bottom="10dip"
android:left="10dip"
android:right="10dip" />
<stroke
android:width="2dip"
android:color="#CCCCCC" />
</shape>




backimage.xml drawableに置きます
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:tileMode="repeat"
    android:src="@drawable/ic_launcher" />




SpinnerTestActivity.java
package spinner.test.namespace;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class SpinnerTestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String[] s_items = {"RED", "BLUE", "BLACK", "YELLOW", "GREEN"};
        //普通のSpinner
        Spinner spinner1 = (Spinner)findViewById(R.id.spinner1);
        ArrayAdapter<String> adapter1 =
    		new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, s_items);
        adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner1.setAdapter(adapter1);
        //カスタマイズSpinner
        Spinner spinner2 = (Spinner)findViewById(R.id.spinner2);
        //spinner2.setBackgroundColor(Color.parseColor("#AAFFFFFF"));//スピナーの背景色を指定
        spinner2.setBackgroundDrawable(getResources().getDrawable(R.drawable.list_border));//スピナーの背景画像を指定
        IntentItemArrayAdapter adapter2 =
        	new IntentItemArrayAdapter(this, android.R.layout.simple_spinner_item, s_items);
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner2.setAdapter(adapter2);
    }

    private class IntentItemArrayAdapter extends ArrayAdapter<String> {
        private int resourceId;
        private int resourceId2;
        public IntentItemArrayAdapter(Context context, int resourceId, String[] items) {
            super(context, resourceId,items);
            this.resourceId = resourceId;
            this.resourceId2 = resourceId;
        }
        public void setDropDownViewResource(int resourceId2){
            this.resourceId2 = resourceId2;
        }
        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) getContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(resourceId2, null);
            }
            TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
            String cs=this.getItem(position);
            tv.setText(cs);
            tv.setTextColor(Color.parseColor(cs));//ここでリストの文字色を指定
            //((View) parent.getParent()).setBackgroundColor(Color.parseColor("#AAFFFFFF"));//リストの背景色を指定
            ((View) parent.getParent()).setBackgroundDrawable(getResources().getDrawable(R.drawable.list_border));//リストの背景画像を指定
            return convertView;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) getContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(resourceId, null);
            }
            TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
            String cs=this.getItem(position);
            tv.setText(cs);
            tv.setTextColor(Color.parseColor(cs));//ここでスピナの文字色を指定
              return convertView;
        }
    }


}



【おまけ】
このコードだとListが一行書き換わるたびに変更することになって、無駄が多いように思えます。
きっと他にうまい方法があるのでしょう。

【おまけ2】
Spinnerについてはmain.xmlファイル内の指定で
<Spinner
        android:id="@+id/spinner2"
        android:background="@drawable/list_border"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
とすることもできます。

TOPに戻る
2012/4/25