2011年6月12日日曜日

android カラーピッカー?カラーセレクター? ダイアログ

カラーピッカーと言うのか、カラーセレクターと言うのかわからないけど、まあカラーが選択できるダイアログのコードを公開します。SSは、2.2バージョンのエミュレーターです。バージョンによってダイアログの色とか変わるんですねぇ(知らなかったですわ

※マーケットに上げているのは色選択数を変更しています。

独自で作っているので 変な書き方してる部分は多めに見てください。なんせ、動けばいいわ程度でかいてますから・・・
■/drawable(各シークバーのスタイル定義)
color_picker_seekbar_r.xml(赤色のシークバースタイル)
color_picker_seekbar_g.xml(緑色のシークバースタイル)
color_picker_seekbar_b.xml(青色のシークバースタイル)
■/layout(各レイアウト)
main.xml(適当なメイン画面)
dialog_picker.xml(シークバーがあるダイアログ)
dialog_selecter.xml(カラーパレットがあるダイアログ)
■/values(文字)
strings.xml
■/src(ソース)
ColorSelectDialog.java
■マーケットURI
https://market.android.com/details?id=jp.hiro711.ColorSelectDialog&feature=more_from_developer
マーケットに上げておきますんで、DLして使ってみてください。

まったくコメントないですが・・・そんなに大変なコードじゃないので大丈夫だと思います。
カラーセレクトダイアログも、AlertDialog.Builderで作りたかったんですがGridViewを使ったら選択後すぐにダイアログを破棄できなかったんで、こんな作りになってしまいました。
普通のListViewで、16色くらいからの選択ならArrayAdapterでアダプターを作ってgetViewをオーバーライドして背景を変えてやって、AlertDialog.BuilderのsetAdapterでやればリストのXMLを作らなくても簡単にできます。注意するところは、setAdapterのOnClickListener実装時にDialogInterface.OnClickListenerを実装してやって、onClick時の最後にdialog.dismiss()でダイアログ破棄してやるくらいかな。

color_picker_seekbar_r.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
    <shape>     
        <corners android:radius="5dip" />      
            <gradient          
                android:startColor="#ff000000"         
                android:centerY="0.5"         
                android:endColor="#ffff0000"         
                android:angle="0"     
            />    
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
         <shape>
          <corners android:radius="5dip" />
          <gradient
           android:startColor="#ff000000"
           android:centerY="0.5"         
           android:endColor="#ffff0000"         
           android:angle="0"       
          />      
         </shape>    
        </clip>  
    </item>
</layer-list>


color_picker_seekbar_g.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:id="@android:id/background">
     <shape>     
         <corners android:radius="5dip" />      
            <gradient          
             android:startColor="#ff000000"         
             android:centerY="0.5"         
             android:endColor="#ff00ff00"         
             android:angle="0"     
            />    
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
         <shape>
          <corners android:radius="5dip" />
          <gradient
           android:startColor="#ff000000"
           android:centerY="0.5"         
           android:endColor="#ff00ff00"         
           android:angle="0"       
          />      
         </shape>    
        </clip>  
    </item>
</layer-list>
color_picker_seekbar_b.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:id="@android:id/background">
     <shape>     
         <corners android:radius="5dip" />      
            <gradient          
             android:startColor="#ff000000"         
             android:centerY="0.5"         
             android:endColor="#ff0000ff"         
             android:angle="0"     
            />    
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
         <shape>
          <corners android:radius="5dip" />
          <gradient
           android:startColor="#ff000000"
           android:centerY="0.5"         
           android:endColor="#ff0000ff"         
           android:angle="0"       
          />      
         </shape>    
        </clip>  
    </item>
</layer-list>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 <Button android:id="@+id/changeTextColorButton"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="Change Text Color"
  />
 <Button android:id="@+id/changeBackgroundColorButton"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="Change Background Color"
  />
 <TextView android:id="@+id/sampleTextView1"
  android:layout_width="fill_parent"
  android:layout_height="40dp"
  android:gravity="center_vertical|center_horizontal"
  android:textSize="20dp"
  android:text="Sample1"/>
</LinearLayout>
dialog_picker.xml
<?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:padding="4dp"
   android:orientation="vertical">
    <TextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"
     android:paddingRight="5dp"
     android:text="@string/color_picker_viewer"/>
    <TextView android:id="@+id/colorPickerViewer"
     android:layout_width="fill_parent"
     android:layout_height="40dp"
     android:layout_marginLeft="5dp"
     android:layout_marginRight="5dp"/>
    <TextView android:id="@+id/colorPickerTextR"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"
     android:paddingTop="5dp"/>
    <SeekBar android:id="@+id/colorPickerSeekBarR"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:max="255"
     android:padding="8dp"
     android:progressDrawable="@drawable/color_picker_seekbar_r"/>
    <TextView android:id="@+id/colorPickerTextG"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"/>
    <SeekBar android:id="@+id/colorPickerSeekBarG"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:max="255"
     android:padding="8dp"
     android:progressDrawable="@drawable/color_picker_seekbar_g"/>
    <TextView android:id="@+id/colorPickerTextB"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"/>
    <SeekBar android:id="@+id/colorPickerSeekBarB"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:max="255"
     android:padding="8dp"
     android:progressDrawable="@drawable/color_picker_seekbar_b" />
</LinearLayout>
dialog_selecter.xml
<?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:orientation="vertical"
 >
    <GridView android:id="@+id/colorSelectGridView"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:verticalSpacing="6dp"
     android:horizontalSpacing="6dp"
     android:numColumns="4"/>
</LinearLayout>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, ColorSelectDialog!</string>
    <string name="app_name">Color Select Dialog</string>
    <string name="color_picker_viewer">Color Viewer(Click to select 16Color)</string>
    <string name="color_picker_red">RED</string>
    <string name="color_picker_green">GREEN</string>
    <string name="color_picker_blue">BLUE</string>
</resources>
ColorSelectDialog.java
package jp.hiro711.ColorSelectDialog;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class ColorSelectDialog extends Activity {
    final int CHANGE_TEXT = 0;
    final int CHANGE_BACKGROUND = 1;

    final int COLOR_TABLE[] = {
        0xffffffff, 0xffc0c0c0, 0xff808080, 0xff000000,
        0xffffc0c0, 0xffff6060, 0xffff0000, 0xff800000,
        0xffffe0c0, 0xffffb060, 0xffff8000, 0xff804000,
        0xffffffc0, 0xffffff60, 0xffffff00, 0xff808000,
        0xffe0ffc0, 0xffb0ff60, 0xff80ff00, 0xff408000,
        0xffc0ffc0, 0xff60ff60, 0xff00ff00, 0xff008000,
        0xffc0ffe0, 0xff60ffb0, 0xff00ff80, 0xff008040,
        0xffc0ffff, 0xff60ffff, 0xff00ffff, 0xff008080,
        0xffc0e0ff, 0xff60b0ff, 0xff0080ff, 0xff004480,
        0xffc0c0ff, 0xff6060ff, 0xff0000ff, 0xff000080,
        0xffe0c0ff, 0xffb060ff, 0xff8000ff, 0xff400080,
        0xffffc0ff, 0xffff60ff, 0xffff00ff, 0xff800080,
        0xffffc0e0, 0xffff60b0, 0xffff0080, 0xff800040
    };

    int mColor = 0xffffffff;
    int mTextColor = 0xffc0c0c0;
    int mBackgroundColor = 0xff000000;

    LayoutInflater inflater;  
    View dialogView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        final Button button1 = (Button)findViewById(R.id.changeTextColorButton);
        button1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mColor = mTextColor;
                colorDialog(CHANGE_TEXT);
            }
        });
        final Button button2 = (Button)findViewById(R.id.changeBackgroundColorButton);
        button2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mColor = mBackgroundColor;
                colorDialog(CHANGE_BACKGROUND);
            }
        });
    }
   
    private void colorDialog(final int where) {
        final String rString = getResources().getString(R.string.color_picker_red);
        final String gString = getResources().getString(R.string.color_picker_green);
        final String bString = getResources().getString(R.string.color_picker_blue);

        inflater = LayoutInflater.from(this);  
        dialogView = inflater.inflate(R.layout.dialog_picker, null);
       
        final TextView textR = (TextView)dialogView.findViewById(R.id.colorPickerTextR);
        textR.setText(String.format("%s(%02X)", rString, (mColor & 0x00ff0000) >> 16));
        final TextView textG = (TextView)dialogView.findViewById(R.id.colorPickerTextG);
        textG.setText(String.format("%s(%02X)", gString, (mColor & 0x0000ff00) >> 8));
        final TextView textB = (TextView)dialogView.findViewById(R.id.colorPickerTextB);
        textB.setText(String.format("%s(%02X)", bString, (mColor & 0x000000ff)));
        final TextView viewer = (TextView)dialogView.findViewById(R.id.colorPickerViewer);
        viewer.setBackgroundColor(mColor);
        viewer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog(0);
            }
        });
       
        final SeekBar seekBarR = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarR);
        seekBarR.setProgress((mColor & 0x00ff0000) >>16);
        seekBarR.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textR.setText(String.format("%s(%02X)", rString, value));
            mColor = (mColor & 0xff00ffff) | value << 16;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textR.setText(String.format("%s(%02X)", rString, value));
            mColor = (mColor & 0xff00ffff) | value << 16;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            int value = seekBar.getProgress();
            textR.setText(String.format("%s(%02X)", rString, value));
            mColor = (mColor & 0xff00ffff) | value << 16;
            viewer.setBackgroundColor(mColor);
        }
    });
    final SeekBar seekBarG = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarG);
    seekBarG.setProgress((mColor & 0x0000ff00) >> 8);
    seekBarG.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textG.setText(String.format("%s(%02X)", gString, value));
            mColor = (mColor & 0xffff00ff) | value << 8;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textG.setText(String.format("%s(%02X)", gString, value));
            mColor = (mColor & 0xffff00ff) | value << 8;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            int value = seekBar.getProgress();
            textG.setText(String.format("%s(%02X)", gString, value));
            mColor = (mColor & 0xffff00ff) | value << 8;
            viewer.setBackgroundColor(mColor);
        }
    });
    final SeekBar seekBarB = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarB);
    seekBarB.setProgress((mColor & 0x000000ff));
    seekBarB.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
                int value = seekBar.getProgress();
            textB.setText(String.format("%s(%02X)", bString, value));
            mColor = (mColor & 0xffffff00) | value;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textB.setText(String.format("%s(%02X)", bString, value));
            mColor = (mColor & 0xffffff00) | value;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            int value = seekBar.getProgress();
            textB.setText(String.format("%s(%02X)", bString, value));
            mColor = (mColor & 0xffffff00) | value;
            viewer.setBackgroundColor(mColor);
        }
    });
    final AlertDialog.Builder alert = new AlertDialog.Builder(this);  
    alert.setView(dialogView);     
    alert.setPositiveButton("OK", new DialogInterface.OnClickListener(){  
        @Override 
        public void onClick(DialogInterface dialog, int idx) {
            switch(where) {
            case CHANGE_TEXT:
                mTextColor = mColor;
                final TextView textView0 = (TextView)findViewById(R.id.sampleTextView1);
                textView0.setTextColor(mTextColor);
                break;
            case CHANGE_BACKGROUND:
                mBackgroundColor = mColor;
                final TextView textView1 = (TextView)findViewById(R.id.sampleTextView1);
                textView1.setBackgroundColor(mBackgroundColor);
                break;
            }
        }
    });  
    alert.show();
}

@Override
protected Dialog onCreateDialog(int id) {
    if(id == 0) {
        final String rString = getResources().getString(R.string.color_picker_red);
        final String gString = getResources().getString(R.string.color_picker_green);
        final String bString = getResources().getString(R.string.color_picker_blue);

        LayoutInflater inflater1 = LayoutInflater.from(this);  
        final View dialogView1 = inflater1.inflate(R.layout.dialog_selecter, null);
        
        final GridView gridView = (GridView)dialogView1.findViewById(R.id.colorSelectGridView);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,   android.R.layout.simple_list_item_1) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                view.setBackgroundColor(COLOR_TABLE[position]);
                return view;
            }
       };
       for(int i = 0; i<COLOR_TABLE.length; i++) {
           adapter.add("");
       }
       gridView.setAdapter(adapter);
       gridView.setOnItemClickListener(new OnItemClickListener() {
           @Override
           public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
               mColor = COLOR_TABLE[arg2];
               final TextView textR = (TextView)dialogView.findViewById(R.id.colorPickerTextR);
               textR.setText(String.format("%s(%02X)", rString, (mColor & 0x00ff0000) >> 16));
               final TextView textG = (TextView)dialogView.findViewById(R.id.colorPickerTextG);
               textG.setText(String.format("%s(%02X)", gString, (mColor & 0x0000ff00) >> 8));
               final TextView textB = (TextView)dialogView.findViewById(R.id.colorPickerTextB);
               textB.setText(String.format("%s(%02X)", bString, (mColor & 0x000000ff)));
               final TextView viewer = (TextView)dialogView.findViewById(R.id.colorPickerViewer);
               viewer.setBackgroundColor(mColor);
               final SeekBar seekBarR = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarR);
               seekBarR.setProgress((mColor & 0x00ff0000) >>16);
               final SeekBar seekBarG = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarG);
               seekBarG.setProgress((mColor & 0x0000ff00) >> 8);
               final SeekBar seekBarB = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarB);
               seekBarB.setProgress((mColor & 0x000000ff));
               dismissDialog(0);
           }
       });

       return new AlertDialog.Builder(this)
            .setView(dialogView1)
            .setNegativeButton("Cancel", null)
            .create();
       }
       return super.onCreateDialog(id);
    }
}

4 件のコメント:

  1. Thank you. I cannot actually read this post, but I have made good use of your code. It works great! It looks like you are linked to from a couple of english sites.

    Phillip Scott Givens
    www.phillipscottgivens.com

    返信削除
  2. とてもいいコードを公開していただき、ありがとうございます。
    完璧なカラーピッカーです。
    利用させていただきます。
    感謝、感謝です。

    返信削除
  3. 素晴らしいカラーピッカーだと思います。
    公開していただき、ありがとうございます。
    利用させて頂きます!

    返信削除
  4. これを求めていました!
    公開してくださってありがとうございます!
    利用させていただきます。

    返信削除