尽管设置了必要的属性,列表项仍不会保持选中

时间:2015-07-15 22:10:41

标签: java android xml android-fragments android-listview

我正在尝试在列表视图中选择所选项目以便在我选择它时保持突出显示但由于某种原因,当所选项目不在视图中时它将不会这样做。例如。当我选择第4项时,该列表项会突出显示,但是当我滚动列表时,它不会保持突出显示,然后其他项随机突出显示。即使我返回第4项,该项目也不再突出显示。我真的不明白为什么会这样。如何解决此问题?所有相关的帮助将不胜感激。

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(在“数据”包中)

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>

更新截图31/07/2015 enter image description here

1 个答案:

答案 0 :(得分:2)

Android ListView在滚动时重复使用其视图。您需要在项目对象中存储有关所选项目的信息,并检查它是否在getView中选中。

如果已选中则调用setItemSelected,否则调用setItemNormal。这样,您可以在滚动列表时更新每个项目的选定状态。

修改

@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;
}

onItemClick内:

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