ListView.setSelector(...)无法将正确的背景颜色应用于所选项目

时间:2019-08-07 23:40:01

标签: java android listview

Tl; dr:我使用的是ListView的setSelector(...)来更改所选项目的背景颜色,尽管颜色确实发生了变化,但它选择的是默认颜色,而不是我想要的颜色。

我想创建一个ListView,一次只允许选择一个项目。 (几乎)一切正常,但是无论我尝试了什么,所选项目始终使用默认颜色上色。这是我的代码:

ListView:

<android.support.constraint.ConstraintLayout
    android:id="@+id/account_picker_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/rounded_corner_button" >

    <ListView
        android:id="@+id/account_picker_list"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/account_picker_list_corner"
        android:backgroundTint="@color/white"
        android:choiceMode="singleChoice"
        android:listSelector="@drawable/selection_effect"
        app:layout_constraintBottom_toTopOf="@+id/account_picker_divider2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </ListView>

    [...]
</android.support.constraint.ConstraintLayout>

selection_effect.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@color/highlightColor" android:state_activated="false"/>
<item android:drawable="@color/green" android:state_pressed="true"/>
<item android:drawable="@color/red" android:state_activated="true"/>
<item android:drawable="@color/colorAccent" android:state_focused="true"/>
<item android:drawable="@color/lightred" android:state_enabled="true"/>
<item android:drawable="@color/lightgreen" android:state_checked="true"/>
<item android:drawable="@color/colorAccentLight" android:state_active="true"/>
<item android:drawable="@color/buttonColor" android:state_selected="true"/>
<item android:drawable="@android:color/black" android:state_hovered="true"/>
<item android:drawable="@color/red" android:state_window_focused="true"/>
<item android:drawable="@color/red" android:state_single="true"/>
</selector>

管理ListView的活动中的相关代码:

private void createAccountViewAdapter() {
    // Create the adapter to convert the array to views
    ArrayList<Account> al = new ArrayList<>();

    if (accountViewAdapter == null) {
        accountViewAdapter = new AccountPickerViewAdapter(this, al, this);
    }

    ListView listView = findViewById(R.id.account_picker_list);
    listView.setSelector(R.drawable.selection_effect);
    listView.setAdapter(accountViewAdapter);

    updateAccountViewAdapter();
}

public void updateAccountViewAdapter() {
    TextView noAccounts = findViewById(R.id.account_picker_no_account);
    ArrayList<Account> al = new ArrayList<>();
    if (!AccountHandler.getAllAccounts().isEmpty()) {
        al = AccountHandler.getAllAccounts();
        noAccounts.setText("");
    } else {
        noAccounts.setText(getResources().getString(R.string.no_accounts));
    }
    accountViewAdapter.refreshItems(al);
}

自定义ListView适配器仅实现getView(...),并且不以任何方式更改背景颜色。 从selection_effect.xml中的语句中可以看到,我已经尝试了android让我使用的可能状态的每种组合,不用说,应用程序中显示的实际颜色不在我上面定义的颜色之中。我想念什么?

编辑:原来该应用使用的是我为相关活动设置的AppTheme的默认颜色。在更改styles.xml中的默认颜色之后,所选颜色现在默认为新颜色。但是,我仍然不明白为什么我不能为所选项目设置自定义颜色。

<activity
        android:name=".AccountPicker"
        android:theme="@style/AppTheme.Popup">
</activity>

<style name="AppTheme.Popup" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowCloseOnTouchOutside">true</item>
    <item name="colorPrimary">@color/colorAccentLight</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Edit2:这是 AccountPickerViewAdapter 类:

public class AccountPickerViewAdapter extends ArrayAdapter<Account> {
ArrayList<Account> accounts;
Activity intent;

public AccountPickerViewAdapter(Context context, ArrayList<Account> accounts, Activity intent) {
    super(context, 0, accounts);
    this.intent = intent;
    this.accounts = accounts;
}

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

    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.account_picker_item, parent, false);
    }

    final Account myAccount = getItem(position);

    TextView name = convertView.findViewById(R.id.account_picker_item_name);
    TextView balance = convertView.findViewById(R.id.account_picker_item_balance);
    TextView description = convertView.findViewById(R.id.account_picker_item_description);
    Button confirm = convertView.findViewById(R.id.account_picker_item_confirm);

    name.setText(myAccount.getName());
    balance.setText(AccountHelper.stringifyBigDec(myAccount.getBalance(), false, true, myAccount.getId()));
    description.setText(myAccount.getDescription());
    /*
    confirm.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AccountHandler.setActiveAccount(myAccount.getId());

            intent.finish();
        }
    });

    confirm.setOnLongClickListener(new View.OnLongClickListener() {
        public boolean onLongClick(View v) {
            return true;
        }
    });

    */

    return convertView;
}

public void refreshItems(ArrayList<Account> items) {
    this.accounts.clear();
    this.accounts.addAll(items);
    notifyDataSetChanged();
}
}

1 个答案:

答案 0 :(得分:0)

isSelected类添加一个名为Account的额外属性。

class Account {
    ... other attributes
    private boolean isSelected;
}

getView的{​​{1}}中:

AccountPickerViewAdapter

在列表视图的final Account myAccount = getItem(position); if (myAccount.isSelected()) { // set selected background } else { // set default background } 中,将onItemClick设置为点击的帐户项目为true。

或者,对于其他方法,请参见此question