新作アプリ「こづかい帳」の開発を進める中で以前投稿した複数列のリストについて、機能改善を行ったので本日はそちらの共有です。
本対応の目的
基本的な内容は以前の投稿を参照ください。
今回の機能改善により、主に下記2点を実現しました。
- リストデータを押下した際に対象の背景色を変更する。
- リストデータを押下した際にリストに表示されていない情報も扱えるようにする。
サンプルコードを画面キャプチャするとこんな感じです。
8/17の行をクリックすると行全体の色が反転します。
そしてリスト上に表示されていない情報をToast表示します。
layoutの準備
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/title1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="@dimen/sp_m" android:layout_weight="3" android:gravity="center" android:layout_marginRight="@dimen/dp_s" android:layout_marginBottom="@dimen/dp_s" android:padding="@dimen/dp_m" android:background ="@color/title" android:text="@string/title1"/> <TextView android:id="@+id/title2" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="@dimen/sp_m" android:layout_weight="2" android:gravity="center" android:layout_marginRight="@dimen/dp_s" android:layout_marginBottom="@dimen/dp_s" android:padding="@dimen/dp_m" android:background ="@color/title" android:text="@string/title2"/> <TextView android:id="@+id/title3" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="@dimen/sp_m" android:layout_weight="3" android:gravity="center" android:layout_marginBottom="@dimen/dp_s" android:padding="@dimen/dp_m" android:background ="@color/title" android:text="@string/title3"/> </LinearLayout> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>メインのレイアウトファイルは、ListViewのidを変更したのみです。
raw.xmlは前回のまま変更なしです。
drawableの準備
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/transparent" android:state_selected="true" android:state_window_focused="false"/> <item android:drawable="@android:color/transparent" android:state_selected="true"/> <item android:drawable="@android:color/transparent" android:state_pressed="true" android:state_selected="false"/> <item android:drawable="@color/data1" android:state_selected="false"/> </selector><?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/transparent" android:state_selected="true" android:state_window_focused="false"/> <item android:drawable="@android:color/transparent" android:state_selected="true"/> <item android:drawable="@android:color/transparent" android:state_pressed="true" android:state_selected="false"/> <item android:drawable="@color/data2" android:state_selected="false"/> </selector>今回新たに追加したファイルです。リストの背景色を通常時、押下時等に場合分けて定義しています。
valuesの準備
colors.xml、dimens.xml、string.xmlのいずれも前回のまま変更点はありません。
Java側の記載
package jp.co.skys.android.sample; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Typeface; import android.os.Bundle; import android.support.v4.content.res.ResourcesCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; //Ver1からの変更点:ListActivity ⇒ Activityへ戻す public class multipleRowListSample2 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // サンプル用のデータを準備 List<Data> dataList = new ArrayList<>(); // 現在時刻取得 Date dt = new Date(); long timestamp = dt.getTime(); // サンプル用のデータを詰め込む for (int i = 0; i <= 100; i++) { Data data = new Data(); data.setLongData(timestamp - 86400000 * (long) i); data.setStringData(String.valueOf(i) + ":abcdefghijklmnopqrstuvwxyz"); data.setIntData(i * i * i); data.setHiddenData("hiddenData:"+String.valueOf(i)); dataList.add(data); } /*Ver1からの変更点:リストを押下された場合の処理を追加 ・押下したデータの背景色が変わる ・押下時にリストに表示されていない情報をToastで表示*/ ListView listView = (ListView) findViewById(R.id.list); ListAdapter adapter = new ListAdapter(this, dataList); listView.setAdapter(adapter); listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ListView listView = (ListView) parent; listView.setItemChecked(position, true); Data item = (Data) listView.getAdapter().getItem(position); Toast.makeText(parent.getContext(), item.getHiddenData(), Toast.LENGTH_LONG).show(); } }); } } // データ格納用クラス class Data { private long longData; //日付用 private String stringData; //文言用 private int intData; //数値用 //Ver1からの変更点:画面上のリストには表示しないデータを追加 private String hiddenData; public void setLongData(long tmp) { this.longData = tmp; } public long getLongData() { return longData; } public void setStringData(String tmp) { this.stringData = tmp; } public String getStringData() { return stringData; } public void setIntData(int tmp) { this.intData = tmp; } public long getIntData() { return intData; } public void setHiddenData(String tmp) { this.hiddenData = tmp; } public String getHiddenData() { return hiddenData; } } // LIST表示制御用クラス //Ver1からの変更点:extends ArrayAdapter<Data> を extends BaseAdapterに変更 class ListAdapter extends BaseAdapter { private List<Data> list; private LayoutInflater inflater; private Resources r; public ListAdapter(Context context, List<Data> list) { super(); this.list = list; inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); r = context.getResources(); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View view, ViewGroup parent) { // layout/raw.xmlを紐付ける if (view == null) view = inflater.inflate(R.layout.raw, null); Data data = (Data) getItem(position); TextView tvData1 = (TextView) view.findViewById(R.id.raw1); TextView tvData2 = (TextView) view.findViewById(R.id.raw2); TextView tvData3 = (TextView) view.findViewById(R.id.raw3); if (data != null) { SimpleDateFormat ymd = new SimpleDateFormat("MM/dd", Locale.JAPANESE); tvData1.setText(ymd.format(data.getLongData())); tvData2.setText(data.getStringData()); tvData3.setText(String.format("%1$,3d", data.getIntData())); } //Ver1からの変更点:固定幅のフォントに設定 tvData2.setTypeface(Typeface.MONOSPACE); // 条件によってリストアイテムの背景色を変更 if(position%2 == 0) { /*Ver1からの変更点:colorを指定するのではなく、drawable配下のdata1.xml、data2.xmlを指定。 minSdkVersionを16以上とする必要あり。*/ tvData1.setBackground(ResourcesCompat.getDrawable(r, R.drawable.data1, null)); tvData2.setBackground(ResourcesCompat.getDrawable(r, R.drawable.data1, null)); tvData3.setBackground(ResourcesCompat.getDrawable(r, R.drawable.data1, null)); }else{ tvData1.setBackground(ResourcesCompat.getDrawable(r, R.drawable.data2, null)); tvData2.setBackground(ResourcesCompat.getDrawable(r, R.drawable.data2, null)); tvData3.setBackground(ResourcesCompat.getDrawable(r, R.drawable.data2, null)); } return view; } }主な変更点は、ソース内のコメントにてご確認ください。
最後に
上記一式含まれるファイルを下記よりダウンロードできます。
良かったらご参考まで