List item won't stay selected despite setting necessary properties

旧街凉风 提交于 2019-12-08 13:48:36

问题


I'm trying to get the selected item within my list view to stay highlighted when I select it but for some reason it won't do that the moment the selected item is not in view. E.g. When I select Item 4, that list item does get highlighted but when I scroll through the list it doesn't stay highlighted and then other items randomly become highlighted. Even when I return to Item 4, that item is no longer highlighted. I really don't understand why this is happening. What can be done to resolve this issue? All relevant help would be appreciated.

fragment_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="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragmentmain">

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="false"
        android:layout_centerHorizontal="true"
        android:choiceMode="singleChoice"/>
</LinearLayout>

MainListAdapter.java

public class MainListAdapter extends BaseAdapter implements Filterable {

    private List<Main> mData;
    private List<Main> mFilteredData;
    private LayoutInflater mInflater;
    private ItemFilter mFilter;

    public MainListAdapter (List<Main> data, Context context) {
        mData = data;
        mFilteredData = new ArrayList(mData);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return mFilteredData.size();
    }

    @Override
    public Main getItem(int position) {
        return mFilteredData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

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

        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item, parent, false);
            holder = new ViewHolder();

            holder.title = (TextView) convertView.findViewById(R.id.item);
            holder.description = (TextView) convertView.findViewById(R.id.item_description);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Main main = getItem(position);
        holder.title.setText(main.getContinent());
        holder.description.setText(main.getDescription());
        if (main.isSelected()) {
            convertView.setBackgroundColor(Color.parseColor("#1C3F96"));
            holder.title.setTextColor(Color.parseColor("#FFFFFF"));
            holder.description.setTextColor(Color.parseColor("#FFFFFF"));
        } else {
            convertView.setBackgroundColor(Color.TRANSPARENT);
            holder.title.setTextColor(Color.parseColor("#FFFFFF"));
            holder.description.setTextColor(Color.parseColor("#B5B5B5"));
        }

        holder.title.setText(mFilteredData.get(position).getContinent());
        holder.description.setText(mFilteredData.get(position).getDescription());

        return convertView;
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ItemFilter();
        }
        return mFilter;
    }

    /**
     * View holder
     */
    static class ViewHolder {
        private TextView title;
        private TextView description;
    }

    /**
     * Filter for filtering list items
     */
    /**
     * <p>An array filter constrains the content of the array adapter with
     * a prefix. Each item that does not start with the supplied prefix
     * is removed from the list.</p>
     */
    private class ItemFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            if (TextUtils.isEmpty(constraint)) {
                results.count = mData.size();
                results.values = new ArrayList(mData);
            } else {
                //Create a new list to filter on
                List<Main> resultList = new ArrayList<Main>();
                for (Main str : mData) {
                    if (str.getContinent().toLowerCase().contains(constraint.toString().toLowerCase())) {
                        resultList.add(str);
                    }
                }
                results.count = resultList.size();
                results.values = resultList;
            }
            return results;
        }

        /**
         * Runs on ui thread
         * @param constraint the constraint used for the result
         * @param results the results to display
         */
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results.count == 0) {
                mFilteredData.clear();
                notifyDataSetInvalidated();
            } else {
                mFilteredData = (ArrayList<Main>)results.values;
                notifyDataSetChanged();
            }
        }
    }
}

Main.java (in the "data" package)

public class Main {
    public Main(){}

    private String continent;
    private String description;
    private boolean selected;

    public String getContinent(){
        return continent;
    }

    public void setContinent(String continent){
        this.continent = continent;
    }

    public String getDescription(){
        return description;
    }

    public void setDescription(String description){
        this.description = description;
    }

    private int _id;
    public void getID(int _id){
        this._id = _id;
    }

    public int setID(){
        return _id;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }
}

MainActivity.java

public class MainActivity extends ActionBarActivity {

    private boolean mTwoPane;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        FragmentMain newFragment = new FragmentMain();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.master_container, newFragment);
        transaction.commit();

        if (findViewById(R.id.detail_container) != null) {
            mTwoPane = true;

        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        handleIntent(intent);
    }

    private void handleIntent(Intent intent) {

        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            //use the query to search your data somehow
        }
    }
}

FragmentMain.java

public class FragmentMain extends ListFragment implements SearchView.OnQueryTextListener {
    private MainListAdapter mAdapter;

    public FragmentMain() {
        // Required empty constructor
    }

    /**
     * Whether or not the activity is in two-pane mode, i.e. running on a tablet
     * device.
     */
    public boolean mTwoPane;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);

        //Tell the system to call onCreateOptionsMenu
        setHasOptionsMenu(true);
        initialize(view);
        return view;
    }

    List<Main> list = new ArrayList<>();
    private void initialize(View view) {
        String[] items = getActivity().getResources().getStringArray(R.array.items);
        String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.item_descriptions);
        for (int n = 0; n < items.length; n++){
            Main world = new Main();
            world.setID();
            world.setContinent(items[n]);
            world.setDescription(itemDescriptions[n]);
            list.add(world);
        }

        mAdapter = new MainListAdapter(list, getActivity());
        setListAdapter(mAdapter);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        View v = getView();

        mTwoPane = getActivity().findViewById(R.id.detail_container) != null;


        ListView lv = (ListView)v.findViewById(android.R.id.list);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // get the adapter, then get the name from the adapter at that position
                MainListAdapter adapter = (MainListAdapter) parent.getAdapter();
                Main main = adapter.getItem(position);

                if (mTwoPane) {
                    setItemNormal();
                    View rowView = view;
                    setItemSelected(rowView);


                Fragment newFragment;
                switch (position) {
                    case 0:
                        newFragment = new Fragment0();
                        break;
                    case 1:
                        newFragment = new Fragment1();
                        break;
                    case 2:
                        newFragment = new Fragment2();
                        break;
                    case 3:
                        newFragment = new Fragment3();
                        break;
                    case 4:
                        newFragment = new Fragment4();
                        break;
                    case 5:
                        newFragment = new Fragment5();
                        break;
                    case 6:
                        newFragment = new Fragment6();
                        break;
                    case 7:
                        newFragment = new Fragment7();
                        break;
                    case 8:
                        newFragment = new Fragment8();
                        break;
                    case 9:
                        newFragment = new Fragment9();
                        break;
                    case 10:
                        newFragment = new Fragment10();
                        break;
                    case 11:
                        newFragment = new Fragment11();
                        break;
                    case 12:
                        newFragment = new Fragment12();
                        break;
                    case 13:
                        newFragment = new Fragment13();
                        break;
                    case 14:
                        newFragment = new Fragment14();
                        break;
                    case 15:
                        newFragment = new Fragment15();
                        break;
                    case 16:
                        newFragment = new Fragment16();
                        break;
                    case 17:
                        newFragment = new Fragment17();
                        break;
                    case 18:
                        newFragment = new Fragment18();
                        break;
                    case 19:
                        newFragment = new Fragment19();
                        break;
                    case 20:
                        newFragment = new Fragment20();
                        break;
                    default:
                        newFragment = new Fragment0();
                }
                MainActivity activity = (MainActivity) view.getContext();
                FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                transaction.setCustomAnimations(R.anim.fade_out, R.anim.fade_in);
                transaction.replace(R.id.detail_container, newFragment);
                transaction.commit();
                } else {
                    Intent intent;
                    if (main.equals(view.getResources().getString(R.string.item0))) {
                        intent = new Intent(getActivity(), Activity0.class);
                    } else if (main.equals(view.getResources().getString(R.string.item1))) {
                        intent = new Intent(getActivity(), Activity1.class);
                    } else if (main.equals(view.getResources().getString(R.string.item2))) {
                        intent = new Intent(getActivity(), Activity2.class);
                    } else if (main.equals(view.getResources().getString(R.string.item3))) {
                        intent = new Intent(getActivity(), Activity3.class);
                    } else if (main.equals(view.getResources().getString(R.string.item4))) {
                        intent = new Intent(getActivity(), Activity4.class);
                    } else if (main.equals(view.getResources().getString(R.string.item5))) {
                        intent = new Intent(getActivity(), Activity5.class);
                    } else if (main.equals(view.getResources().getString(R.string.item6))) {
                        intent = new Intent(getActivity(), Activity6.class);
                    } else if (main.equals(view.getResources().getString(R.string.item7))) {
                        intent = new Intent(getActivity(), Activity7.class);
                    } else if (main.equals(view.getResources().getString(R.string.item8))) {
                        intent = new Intent(getActivity(), Activity8.class);
                    } else if (main.equals(view.getResources().getString(R.string.item9))) {
                        intent = new Intent(getActivity(), Activity9.class);
                    } else if (main.equals(view.getResources().getString(R.string.item10))) {
                        intent = new Intent(getActivity(), Activity10.class);
                    } else if (main.equals(view.getResources().getString(R.string.item11))) {
                        intent = new Intent(getActivity(), Activity11.class);
                    } else if (main.equals(view.getResources().getString(R.string.item12))) {
                        intent = new Intent(getActivity(), Activity12.class);
                    } else if (main.equals(view.getResources().getString(R.string.item13))) {
                        intent = new Intent(getActivity(), Activity13.class);
                    } else if (main.equals(view.getResources().getString(R.string.item14))) {
                        intent = new Intent(getActivity(), Activity14.class);
                    } else if (main.equals(view.getResources().getString(R.string.item15))) {
                        intent = new Intent(getActivity(), Activity15.class);
                    } else if (main.equals(view.getResources().getString(R.string.item16))) {
                        intent = new Intent(getActivity(), Activity16.class);
                    } else if (main.equals(view.getResources().getString(R.string.item17))) {
                        intent = new Intent(getActivity(), Activity17.class);
                    } else if (main.equals(view.getResources().getString(R.string.item18))) {
                        intent = new Intent(getActivity(), Activity18.class);
                    } else if (main.equals(view.getResources().getString(R.string.item19))) {
                        intent = new Intent(getActivity(), Activity19.class);
                    } else if (main.equals(view.getResources().getString(R.string.item20))) {
                        intent = new Intent(getActivity(), Activity20.class);
                    } else {
                        intent = new Intent(getActivity(), Activity0.class);
                    }
                    startActivity(intent);
                }
            }

            public void setItemSelected(View view) {
                View rowView = view;
                view.setBackgroundColor(Color.parseColor("#1C3F96"));

                TextView tv0 = (TextView) rowView.findViewById(R.id.item);
                tv0.setTextColor(Color.parseColor("#FFFFFF"));

                TextView tv1 = (TextView) rowView.findViewById(R.id.item_description);
                tv1.setTextColor(Color.parseColor("#FFFFFF"));
            }

            public void setItemNormal() {
                for (int i = 0; i < getListView().getChildCount(); i++) {
                    View v = getListView().getChildAt(i);
                    v.setBackgroundColor(Color.TRANSPARENT);

                    TextView tv0 = ((TextView) v.findViewById(R.id.item));
                    tv0.setTextColor(Color.WHITE);

                    TextView tv1 = ((TextView) v.findViewById(R.id.item_description));
                    tv1.setTextColor(Color.parseColor("#B5B5B5"));
                }
            }
        });

        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        MenuItem searchViewMenuItem = menu.findItem(R.id.action_search);
        SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchViewMenuItem);

        int searchImgId0 = android.support.v7.appcompat.R.id.search_button;
        ImageView v0 = (ImageView) mSearchView.findViewById(searchImgId0);
        v0.setImageResource(R.drawable.ic_action_search_light);

        int searchImgId1 = android.support.v7.appcompat.R.id.search_close_btn;
        ImageView v1 = (ImageView) mSearchView.findViewById(searchImgId1);
        v1.setImageResource(R.drawable.ic_action_content_clear_light);

        super.onPrepareOptionsMenu(menu);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // Set up search view
        inflater.inflate(R.menu.menu_main, menu);
        MenuItem item = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
        searchView.setIconifiedByDefault(true);
        searchView.clearAnimation();
        searchView.setOnQueryTextListener(this);
    }

    @Override
    public boolean onQueryTextSubmit(String newText) {
        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        mAdapter.getFilter().filter(newText);
        return false;
    }
}

list_item.xml

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:baselineAligned="false"
    android:paddingStart="12dp"
    android:paddingEnd="12dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <TextView android:id="@+id/item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:textColor="?android:attr/textColorPrimary" />

        <TextView android:id="@+id/item_description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/item"
            android:layout_alignStart="@id/item"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="?android:attr/textColorSecondary" />
</RelativeLayout>

Updated screenshot 31/07/2015


回答1:


Android ListView reuses its views while you scroll it. You need to store information about a selected item in an item object and check if it is selected inside getView.

Call setItemSelected if it is selected and setItemNormal otherwise. This way you will update the selected state of each item while you scrolling the list.

EDIT

@Override
public Main getItem(int position) {
    return mFilteredData.get(position);
}

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

    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item, parent, false);
        holder = new ViewHolder();

        holder.title = (TextView) convertView.findViewById(R.id.item);
        holder.description = (TextView) convertView.findViewById(R.id.item_description);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    Main main = getItem(position);
    holder.title.setText(main.getContinent());
    holder.description.setText(main.getDescription());
    if (main.isSelected()) {
        convertView.setBackgroundColor(Color.parseColor("#1C3F96"));
        holder.title.setTextColor(Color.parseColor("#FFFFFF"));
        holder.description.setTextColor(Color.parseColor("#FFFFFF"));
    } else {
        convertView.setBackgroundColor(Color.TRANSPARENT);
        holder.title.setTextColor(Color.parseColor("#FFFFFF"));
        holder.description.setTextColor(Color.parseColor("#B5B5B5"));
    }

    return convertView;
}

Inside your onItemClick:

...
switch (position) {
    case 0:
        newFragment = new Fragment0();
        break;
    case 1:
        newFragment = new Fragment1();
        break;
    // etc..
    default:
        newFragment = new Fragment0();
}


来源:https://stackoverflow.com/questions/31442067/list-item-wont-stay-selected-despite-setting-necessary-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!