Как выбрать в коде первый элемент в списке (с базовым адаптером), чтобы изменить его фон

У меня есть список для моего меню с базовым адаптером.

Моя деятельность:

listView_menu = (ListView) findViewById(R.id.listView_menu);
model_category = new Model_Category(context);
listView_menu.setAdapter(new BaseAdapter_Menu(context, model_category.GetAllDifferentCategory()));
listView_menu.setOnItemClickListener(new OnItemClickListener() 
    {
        @Override
        public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3)
        {
            view.setSelected(true);
        }
    });
listView_menu.setSelection(0);

Мой метод getView для BaseAdapter_Menu (расширяет BaseAdapter):

@Override
public View             getView(int position, View convertView, ViewGroup parent)
{
    View                rowView = convertView;

    if (rowView == null)
    {
        rowView = this.inflater.inflate(R.layout.customitemlistview_menu, null);
        ViewHolder viewHolder = new ViewHolder();
        viewHolder.category = (TextView) rowView.findViewById(R.id.category_menu);
        rowView.setTag(viewHolder);
    }
    ViewHolder holder = (ViewHolder)rowView.getTag();
    holder.category.setText(this.data.get(position));
    return (rowView);
}

У каждого элемента есть селектор фона с двумя разными фонами в зависимости от его состояния (ВЫБРАН или НЕТ).

Когда я нажимаю на элемент в своем списке, я устанавливаю свое представление item.setSelected("true").

Итак, когда я нажимаю, фон элемента меняется, но как изменить фон первого элемента моего списка, не нажимая на него. Я уже пробовал 'listView_menu.setSelection(0)', но это не работает.


person user2033147    schedule 01.02.2013    source источник
comment
У меня точно такая же проблема.   -  person Sotti    schedule 01.01.2014


Ответы (4)


Я нашел решение! :)

В моем onCreate я применяю этот код:

listView_menu.setAdapter(new BaseAdapter_Menu(context, model_category.GetAllDifferentCategory()));
    listView_menu.setOnItemClickListener(new OnItemClickListener() 
    {
        @Override
        public void onItemClick(AdapterView<?> listView, View view, int position, long id)
        {
            ((BaseAdapter_Menu) listView_menu.getAdapter()).setPositionSelected(position);
        }
    });

В моем BaseAdater_Menu:

Я создаю private int PositionSelected = 0;

Я добавляю этот метод

public void setPositionSelected(int position)
{
    PositionSelected = position;
    this.notifyDataSetChanged();
}

И я переопределяю метод getView

public View getView(int position, View convertView, ViewGroup parent)
{
    View rowView = convertView;

    if (rowView == null)
    {
        rowView = this.inflater.inflate(R.layout.customitemlistview_menu, null);
        ViewHolder viewHolder = new ViewHolder();
        viewHolder.category = (TextView) rowView.findViewById(R.id.category_menu);
        rowView.setTag(viewHolder);
    }
    ViewHolder holder = (ViewHolder)rowView.getTag();
    holder.category.setText(this.data.get(position));
    if (position == PositionSelected)
        rowView.setBackgroundResource(R.drawable.item_menu_selected_background);
    else
        rowView.setBackgroundResource(R.drawable.item_menu_background);
    return (rowView);
}

Спасибо за помощь :)

person user2033147    schedule 04.02.2013

ОТРЕДАКТИРОВАНО:

Это обходной путь, но я думаю, что он работает: сохраните переменную FisrtTime, которая будет выбирать представление сразу после создания (в BaseAdapter_Menu)

public BaseAdapter_Menu(...){
    ....
    mFirstTime = true;
    ....
}

public getView(int position, ...){
    .... // create your view

    if (mFirstTime && position == 0){
         mFirstTime = false;
         rootView.setSelected(true);
    }

    ... //Setup your view
}
person Corbella    schedule 04.02.2013
comment
У меня есть этот код для изменения фона: ‹selector xmlns:android=schemas.android.com/apk /res/android› ‹item android:state_selected=true android:drawable=@drawable/item_menu_selected_background›‹/item› ‹item android:drawable=@drawable/item_menu_background›‹/item› ‹!-- для других состояние --› ‹/селектор› - person user2033147; 04.02.2013
comment
в порядке. Тогда просто выбор первого представления в конструкторе BaseAdapter_Menu не решит вашу проблему? - person Corbella; 04.02.2013
comment
Как иметь List views в моем конструкторе, потому что представление создается в методе gtView. - person user2033147; 04.02.2013
comment
Изменил мой ответ. Посмотрите, поможет ли вам сейчас. - person Corbella; 04.02.2013
comment
Спасибо, но это не работает :( Я не понимаю, почему setSelected в моем первом представлении не работает! - person user2033147; 04.02.2013

добавьте этот код в свой метод getView():

if(position == 0) {
   rowView.setClickable(true);
   rowView.setSelected(true);
}

ИЗМЕНИТЬ:

Ваш Activity должен реализовать OnItemClickListener следующим образом:

public class YourActivity extends Activity implements OnItemClickListener {

попробуйте это в своем методе onCreate():

//after setting the onItemClickListener to your listView : 
listView_menu.setOnItemClickListener(this);
listView_menu.setSelection(0);
View firstView = listView_menu.getChildAt(0);
onItemClick(listView_menu, firstView, 0, -1);

и извлеките метод onItemClick() в свою деятельность:

@Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
     view.setSelected(true);
}
person Houcine    schedule 01.02.2013
comment
увидеть мои правки; что я сделал в своем коде, так это просто применил код для позиции 0 (первый элемент), это странно, это должно работать. добавьте макет xml вашего элемента строки - person Houcine; 01.02.2013
comment
‹селектор xmlns:android=schemas.android.com/apk/res/android› ‹item android:state_selected=true android:drawable=@drawable/item_menu_selected_background›‹/item› ‹item android:drawable=@drawable/item_menu_background›‹/item› ‹!-- для другого состояния --› ‹/selector› - person user2033147; 01.02.2013
comment
см. мое редактирование (я добавил rowView.setClickable(true);в свой код. добавьте код вашего макета: customitemlistview_menu.xml - person Houcine; 01.02.2013
comment
отредактируйте свой вопрос и добавьте полный код вашего макета customitemlistview_menu.xml и метод onCreate() вашей деятельности - person Houcine; 01.02.2013
comment
У меня есть исключение NullPointerException со строкой: listView_menu.getSelectedView().setSelected(true); - person user2033147; 04.02.2013
comment
Я вижу вашу новую правку, но она не работает. У него нет фона выбранного элемента. Я должен нажать на него, чтобы иметь этот фон. - person user2033147; 04.02.2013
comment
Как вызвать метод onItemClick моего списка в моем onCreate? - person user2033147; 04.02.2013
comment
просто назовите это так, как я сделал в своем редактировании, и скажите мне, работает ли оно, вам просто нужно изменить слушателя вашего ListView на вашу активность, посмотрите мои правки - person Houcine; 04.02.2013
comment
Эта строка неизвестна onItemClick(listView_menu, firstView, 0, -1) для Eclipse. - person user2033147; 04.02.2013
comment
@user2033147 user2033147: посмотрите мои правки, вам нужно извлечь метод onItemClick в свою активность - person Houcine; 04.02.2013
comment
У меня есть NullPointerException со строкой onItemClick(listView_menu, firstView, 0, -1) => view.setSelected(true) - person user2033147; 04.02.2013

res/layout-v11/cell.xml

Если вам нужно разработать приложение только для уровня API 11 позже, все, что вам нужно сделать, это написать следующий код 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="wrap_content"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:orientation="vertical">
    <TextView 
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <TextView 
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

res/layout/cell.xml

Но на уровне API ‹= 10 приведенный выше код вызывает сбои. Так что нужно следовать...

<?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:orientation="vertical">
    <TextView 
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <TextView 
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

DataListCursorAdapter.java

Во-вторых, ваш адаптер должен быть уведомлен о назначении данных.//...(a)

class DataListCursorAdapter extends CursorAdapter {
    private Listener mListener;
    public static class ViewHolder {
        public TextView name;
        public TextView text;
    }
    @SuppressWarnings("deprecation")
    public DataListCursorAdapter(Context context, Cursor c, Listener listener) {
        super(context, c);
        mListener = listener;
    }
    public DataListCursorAdapter(Context context, Cursor c, Listener listener, boolean autoRequery) {
        super(context, c, false);
        mListener = listener;
    }
    public DataListCursorAdapter(Context context, Cursor c, Listener listener, int flags) {
        super(context, c, FLAG_REGISTER_CONTENT_OBSERVER);
        mListener = listener;
    }
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        try {
            ViewHolder holder = (ViewHolder) view.getTag();
            JSONObject json = new JSONObject(cursor.getString(cursor.getColumnIndex(Table.DATA)));
            final Data data = new Data(json);
            mListener.onDataAssigned(data, view);//...(a)

            holder.name.setText(data.name);
            holder.text.setText(data.text);
        }
        catch (JSONException e) {
        }
    }
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.cell, null);
        ViewHolder holder = new ViewHolder();
        holder.name      = (TextView) view.findViewById(R.id.name);
        holder.text      = (TextView) view.findViewById(R.id.text);
        view.setTag(holder);
        return view;
    }
    public interface Listener {
        public void onDataAssigned(Data data, View view);//...(a)
    }
}

YourFragment.java или YourActivity.java

вы реализуете интерфейс и...

@Override
public void onDataAssigned(Data data, View view) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        return;
    }
    if (TextUtils.equals(mLastSelectedDataId, data.id)) {// default color
        view.setBackgroundColor(0xfff7aecb);
    }
    else {// selected color
        view.setBackgroundColor(0x00000000);
    }
}

вы сохраняете выбранный элемент на поле вашего класса.

@Override
public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
    Cursor cursor = mArrayCursorAdapter.getCursor();
    JSONObject json = new JSONObject(cursor.getString(cursor.getColumnIndex(Table.DATA)));
    final Data data = new Data(json);
    if (data != null && TextUtils.equals(mLastSelectedDataId, data.id)) {
        getListView().setItemChecked(position, false);
        mLastSelectedDataId = null;
    }
    else if (data != null) {
        getListView().setItemChecked(position, true);
        mLastSelectedDataId = data.id;
    }
}

Важно

  • В представлении списка количество просмотров элемента не является количеством элемента.
  • Выбранный вид с измененным цветом повторно используется для других данных.

Обновить

public class YourAdapter extends BaseAdapter {
    private LayoutInflater mInflater;
    private Listener mListener;
    private Model_Category mData;

    static class ViewHolder {
        TextView category;
    }
    public YourAdapter(Context context, Model_Category data, LayoutInflater inflater, Listener listener) {
        mInflater = inflater;
        mListener = listener;
        mData = data;
    }
    @Override
    public int getCount() {
        return /*return count*/;
    }
    @Override
    public Object getItem(int position) {
        return /*return item by position*/;
    }
    @Override
    public long getItemId(int position) {
        return /*return id by position*/;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        int type = getItemViewType(position);
        if (convertView == null){
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.customitemlistview_menu, null);
            holder.category = (TextView) convertView.findViewById(R.id.category_menu);
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }
        mListener.onDataAssigned(mData.get(position), convertView);//...(a)
        holder.category.setText(mData.get(position));
        return convertView;
    }
    public interface Listener {
        public void onDataAssigned(Data data, View view);//...(a)
    }
}
person Mitsuaki Ishimoto    schedule 01.02.2013
comment
Это не работает, и у меня есть BaseAdapter, а не CursorAdapter. - person user2033147; 04.02.2013
comment
Этот код фактически работает в моем собственном приложении. Неважно, что вы используете BaseAdapter или любые другие адаптеры. Когда данные элемента списка назначаются, необходимо определить, выбраны ли данные уже или нет, и изменить цвет представления элемента списка. - person Mitsuaki Ishimoto; 04.02.2013
comment
Не могли бы вы рассказать мне, как использовать ваш код с моим BaseAdapter, пожалуйста, спасибо. - person user2033147; 04.02.2013