2011年10月30日日曜日

[android]ListViewのitemの文字色を動的に変更する

結構はまってしまったので、記録。

ListViewに表示されたitemをタップした時に文字色を変更するような処理を実装しようとした所、思いのほか時間がかかってしまいました。

作成したコードを掲載します。該当箇所を抜粋して記載しています。



まずは、ListViewのレイアウトをXMLで定義。

単純にTextViewが1つ配置されているだけのレイアウトになります。

  • list_row


<?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="wrap_content"
android:padding="6dip">
<TextView android:id="@+id/tasktext"
android:layout_width="fill_parent"
android:layout_height="wrap_content" ></TextView>
</LinearLayout>

次に表示する文字列やタップ状態を保持するクラスを作成します。

  • Task


[java]
public class Task {

private String taskName;
private int finishFlag;

public void setTaskName(String task) {
this.taskName = task;
}
public String getTaskName() {
return taskName;
}
public void setFinishFlag(int finishFlah) {
this.finishFlag = finishFlah;
}
public int getFinishFlag() {
return finishFlag;
}

}
[/java]

次にArrayAdapterのサブクラスを定義します。このクラスのgetViewメソッド内で文字列の色を変更します。

  • ListItemAdapter


[java]
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class ListItemAdapter extends ArrayAdapter&lt;Task&gt; {

private ArrayList&lt;Task&gt; items;
private LayoutInflater inflater;

public ListItemAdapter(Context context, int rid, List&lt;Task&gt; list) {
super(context, rid, list);
this.items = (ArrayList&lt;Task&gt;) list;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.list_row, null);
}
Task item = (Task)items.get(position);
if (item != null) {

// TextViewを取得
TextView textView = (TextView)view.findViewById(R.id.tasktext);

// Textを設定
if (textView != null) {
//Log.d("tag", "taskView not null");
textView.setText(item.getTaskName());
Log.d("tag", textView.getText().toString());
}

// 完了状態の時に文字色をグレーアウトする
if (item.getFinishFlag() == 0) {
textView.setTextColor(Color.WHITE);
} else {
textView.setTextColor(Color.GRAY);
}
}
return view;
}

}
[/java]

最後にActivityを作成し、ListViewとAdapterをセットします。

  • 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"
android:weightSum="1">
<ListView android:id="@+id/listView1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"></ListView>
</LinearLayout>


  • MainActivity


[java]
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.database.Cursor;
import android.database.SQLException;
import android.os.Bundle;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {

private List&lt;Task&gt; list;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

list = new ArrayList&lt;Task&gt;();
final ListItemAdapter adapter = new ListItemAdapter(this, R.layout.list_row, list);

// ListView
ListView listView = (ListView) findViewById(id.listView1);
// アダプターをListViewに接続
listView.setAdapter(adapter);

//タスクを作成
Task task = new Task();
task.setTaskName("name1");
task.setFinishFlag = 0;
list.add(task);

// リストビュークリック時のコールバックリスナー
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {
Task task = adapter.getItem(position);
if (task.getFinishFlag() == 0) {
task.setFinishFlag(1);
} else {
task.setFinishFlag(0);
}
adapter.getView(position, view, parent);
}
});
}
}
[/java]

まさか文字色を変更するだけで、こんなに時間がかかるとは思いませんでした。でも一回わかってしまえばなんてことないですね。

0 件のコメント:

コメントを投稿