Выделение элементов ListView в Android
В этой статье я расскажу о том, как сделать так, чтобы элемент в ListView оставался выделенным после того, как пользователь нажмет на него. Дело в том, что по умолчанию в Android каждый дочерний элемент списка выделяется только в тот момент, когда пользователь на него нажимает (или зажимает его). После того как он уберет с него палец — выделение исчезает. Порой в приложении необходимо выделять какой-либо элемент ListView до тех пор, пока пользователь не выберет другой и не нажмет на него. Сделать это несложно.
Предлагаю для примера создать новый проект с одним Activity. После этого нужно будет добавить в Layout-файл для Activity (по умолчанию - activity_main.xml) компонент ListView и дать ему идентификатор, например, my_listview и добавить свойство android:choiceMode="singleChoice". Также нужно будет создать layout для элементов списка (я решил назвать его listview_item.xml). В него нужно добавить LinearLayout с id item_container и текстовое поле (TextView) с id item_text.
Первым делом я задам значения цветов для выделения элемента. Для этого следует создать файл ресурсов colors.xml в папке res/values и добавить в него следующие строки:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="orange">#FF8800</color>
<color name="white">#FFFFFF</color>
<color name="black">#000000</color>
</resources>
Для работы со списком будет использоваться класс MyAdapter, который расширяет класс BaseAdapter и переопределяет его методы. Его нужно будет создать в классе MainActivity.
Поскольку для версий Android API ниже, чем 11 свойство android:state_activated недоступно, то при отображении view-элемента я буду осуществлять проверку того, какая версия Android установлена на устройстве, и если он будет ниже чем 11, то view будет выделяться следующим образом:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
view.setBackgroundColor(Color.WHITE);
textView.setTextColor(Color.BLACK);
if (mListView.isItemChecked(position)) {
view.setBackgroundColor(getResources().getColor(R.color.orange));
textView.setTextColor(Color.WHITE);
}
}
Листинг класса MyAdapter:
class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<String> mItems;
public MyAdapter(LayoutInflater inflater, ArrayList<String> items){
mInflater = inflater;
mItems = items;
}
@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 getView(int position, View convertView, ViewGroup parent) {
TextView textView;
View view;
ViewHolder holder;
if (convertView == null){
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
textView = (TextView) convertView.findViewById(R.id.item_text);
view = convertView.findViewById(R.id.item_container);
textView.setText(mItems.get(position));
holder = new ViewHolder(textView, view);
convertView.setTag(holder);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
view.setBackgroundColor(Color.WHITE);
textView.setTextColor(Color.BLACK);
if (mListView.isItemChecked(position)) {
view.setBackgroundColor(getResources().getColor(R.color.orange));
textView.setTextColor(Color.WHITE);
}
}
}
else{
holder = (ViewHolder) convertView.getTag();
holder.textView.setText(mItems.get(position));
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
holder.view.setBackgroundColor(Color.WHITE);
holder.textView.setTextColor(Color.BLACK);
if (mListView.isItemChecked(position)) {
holder.textView.setTextColor(Color.WHITE);
holder.view.setBackgroundColor(getResources().getColor(R.color.orange));
}
}
}
return convertView;
}
class ViewHolder{
public TextView textView;
public View view;
public ViewHolder(TextView tView, View v){
textView = tView;
view = v;
}
}
}
Теперь в методе onCreate нужно будет создать адаптер и назначить его ListView.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView)findViewById(R.id.my_listview);
ArrayList<String> items = new ArrayList<String>();
for (int i =0; i<10; i++){
items.add("Item - " + String.valueOf(i));
}
MyAdapter adapter = new MyAdapter(getLayoutInflater(), items);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(mItemClickListener);
}
Для того, чтобы элементы списка выделялись после нажатия, нужно будет создать селектор, который будет менять цвет выделения в зависимости от условий. Для этого в папке res нужно создать папку drawable, в которой нужно создать два xml файла с типом selector. Первый нужен для того, чтобы закрашивать фон выделенного View, а второй — чтобы менять цвет текста. Я назвал их item_background_selector.xml и item_text_selector.xml
В первый файл необходимо добавить строки:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@color/orange"></item> <item android:state_pressed="true" android:drawable="@color/orange"></item> <item android:state_pressed="false" android:drawable="@color/white"></item> </selector>
Вo второй файл:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true" android:state_pressed="true" android:color="@color/white" /> <item android:state_enabled="true" android:state_focused="true" android:color="@color/white" /> <item android:state_enabled="true" android:state_selected="true" android:color="@color/white" /> <item android:state_pressed="false" android:color="@color/black"></item> </selector>
После этого нужно открыть файл listview_item.xml и добавить следующее свойство для LinearLayout android:background="@drawable/item_background_selector" а для TextView добавить свойство
android:textColor="@drawable/item_text_selector"
Последнее, что осталось сделать — создать и назначить ListView обработчик нажатия на его элементы с указанием, что его нужно выделить.
public OnItemClickListener mItemClickListener = new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
mListView.setItemChecked(position, true);
mListView.setSelected(true);
}
};
А в метод onCreate нужно добавить строку mListView.setOnItemClickListener(mItemClickListener);
Полный листинг класса MainActivity:
public class MainActivity extends Activity {
private ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView)findViewById(R.id.my_listview);
ArrayList<String> items = new ArrayList<String>();
for (int i =0; i<10; i++){
items.add("Item - " + String.valueOf(i));
}
MyAdapter adapter = new MyAdapter(getLayoutInflater(), items);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(mItemClickListener);
}
public OnItemClickListener mItemClickListener = new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
mListView.setItemChecked(position, true);
mListView.setSelected(true);
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<String> mItems;
public MyAdapter(LayoutInflater inflater, ArrayList<String> items){
mInflater = inflater;
mItems = items;
}
@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 getView(int position, View convertView, ViewGroup parent) {
TextView textView;
View view;
ViewHolder holder;
if (convertView == null){
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
textView = (TextView) convertView.findViewById(R.id.item_text);
view = convertView.findViewById(R.id.item_container);
textView.setText(mItems.get(position));
holder = new ViewHolder(textView, view);
convertView.setTag(holder);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
view.setBackgroundColor(Color.WHITE);
textView.setTextColor(Color.BLACK);
if (mListView.isItemChecked(position)) {
view.setBackgroundColor(getResources().getColor(R.color.orange));
textView.setTextColor(Color.WHITE);
}
}
}
else{
holder = (ViewHolder) convertView.getTag();
holder.textView.setText(mItems.get(position));
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
holder.view.setBackgroundColor(Color.WHITE);
holder.textView.setTextColor(Color.BLACK);
if (mListView.isItemChecked(position)) {
holder.textView.setTextColor(Color.WHITE);
holder.view.setBackgroundColor(getResources().getColor(R.color.orange));
}
}
}
return convertView;
}
class ViewHolder{
public TextView textView;
public View view;
public ViewHolder(TextView tView, View v){
textView = tView;
view = v;
}
}
}
}
Запускаем проект, проверяем, все работает! Если у вас возникли вопросы по примеру — задавайте их в комментариях.
- 9230 просмотров
Добавить комментарий