Search code examples
javaandroidandroid-activityandroid-listviewandroid-listfragment

Replace fragments and start actives based on string name instead of list view item position


Based on my list view, how can I replace the detail container with a particular fragment or start a particular activity based on the name of the string for the item that was selected rather than the position of the item within the list? I'm looking for something like case string rather than case 0, case 1, case 2, etc. The code under inital but incorrect code suggestion is similar to what I'm looking for but not the right solution. All help would be appreciated.

strings

<string-array name="continent_names">
    //item 0    <item>@string/africa</item>
    //item 1    <item>@string/asia</item>
    //item 2    <item>@string/europe</item>
</string-array>

<string-array name="continent_descriptions">
    //item 0    <item>@string/africa_description</item>
    //item 1    <item>@string/asia_description </item>
    //item 2    <item>@string/europe_description </item>
</string-array>

FragmentWorld.java

    public class FragmentWorld extends ListFragment implements SearchView.OnQueryTextListener {

    private WorldListAdapter mAdapter;

    public FragmentWorld() {
        // Required empty constructor
    }

    public static FragmentWorld newInstance() {
        return new FragmentWorld();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_world, container, false);
        setHasOptionsMenu(true);
        initialize(view);
        return view;
    }

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

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

            @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
                WorldListAdapter adapter = (WorldListAdapter) parent.getAdapter();
                String country = adapter.getItem(position);

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

                    Fragment newFragment;
                    if (country.equals(view.getResources().getString(R.string.africa))) {
                        newFragment = new FragmentAfrica();
                    } else if (country.equals(view.getResources().getString(R.string.asia))) {
                        newFragment = new FragmentAsia();
                    } else if (country.equals(view.getResources().getString(R.string.europe))) {
                        newFragment = new FragmentEurope();
                    } else {
                        newFragment = new FragmentAfrica();
                    }
                    WorldActivity activity = (WorldActivity) view.getContext();
                    FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                    transaction.replace(R.id.detail_container, newFragment);
                    transaction.commit();
                } else {
                    Intent intent;
                    if (country.equals(view.getResources().getString(R.string.africa))) {
                        intent = new Intent(getActivity(), AfricaActivity.class);
                    } else if (country.equals(view.getResources().getString(R.string.asia))) {
                        intent = new Intent(getActivity(), AsiaActivity.class);
                    } else if (country.equals(view.getResources().getString(R.string.europe))) {
                        intent = new Intent(getActivity(), EuropeActivity.class);
                    } else {
                        intent = new Intent(getActivity(), AfricaActivity.class);
                    }
                    startActivity(intent);
                }
            }

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

        View close = searchView.findViewById(R.id.search_close_btn);
        close.setBackgroundResource(R.drawable.ic_action_content_clear);
    }

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

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

WorldListAdapter.java

public class WorldListAdapter extends BaseAdapter implements Filterable {

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

    public WorldListAdapter (List<World> 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 String getItem(int position) {
        return mFilteredData.get(position).getName();
    }

    @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_dualline, parent, false);
            holder = new ViewHolder();

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

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

        holder.title.setText(mFilteredData.get(position).getName());
        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;
    }

    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<World> resultList = new ArrayList<World>();
                for (World str : mData) {
                    if (str.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
                        resultList.add(str);
                    }
                }
                results.count = resultList.size();
                results.values = resultList;
            }
            return results;
        }


        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results.count == 0) {
                mFilteredData.clear();
                notifyDataSetInvalidated();
            } else {
                mFilteredData = (ArrayList<World>)results.values;
                notifyDataSetChanged();
            }
        }
    }
}

inital but incorrect code suggestion

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mTwoPane) {
                    setItemNormal();
                    View rowView = view;
                    setItemSelected(rowView);
                    Fragment newFragment;
                    switch (position) {
                        case 0:
                            newFragment = new FragmentAfrica();
                            break;
                        case 1:
                            newFragment = new FragmentAsia();
                            break;
                        case 2:
                            newFragment = new FragmentEurope();
                            break;
                        default:
                            newFragment = new FragmentAfrica();
                            break;
                    }
                    WorldActivity activity = (WorldActivity) view.getContext();
                    FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                    transaction.replace(R.id.detail_container, newFragment);
                    transaction.commit();
                } else {
                    Intent intent;
                    switch (position) {
                        case 0:
                            intent = new Intent(getActivity(), AfricaActivity.class);
                            break;
                        case 1:
                            intent = new Intent(getActivity(), AsiaActivity.class);
                            break;
                        case 2:
                            intent = new Intent(getActivity(), EuropeActivity.class);
                            break;
                        default:
                            intent = new Intent(getActivity(), AfricaActivity.class);
                            break;
                    }
                    startActivity(intent);
                }
            }

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

                TextView tv0 = (TextView) rowView.findViewById(R.id.item_name);
                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 < listView.getChildCount(); i++) {
                    View v = listView.getChildAt(i);
                    v.setBackgroundColor(Color.TRANSPARENT);

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

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

Solution

  • What you want to do is get the adapter from the parent, then get the country name from the adapter.

    Try this:

            @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
                WorldListAdapter adapter = (WorldListAdapter) parent.getAdapter();
                String country = adapter.getItem(position);
    
                if (mTwoPane) {
                    setItemNormal();
                    View rowView = view;
                    setItemSelected(rowView);
    
                    Fragment newFragment;
                    if (country.equals(view.getResources().getString(R.string.africa))) {
                        newFragment = new FragmentAfrica();
                    } else if (country.equals(view.getResources().getString(R.string.asia))) {
                        newFragment = new FragmentAsia();
                    } else if (country.equals(view.getResources().getString(R.string.europe))) {
                        newFragment = new FragmentEurope();
                    } else {
                        newFragment = new FragmentAfrica();
                    }
                    WorldActivity activity = (WorldActivity) view.getContext();
                    FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                    transaction.replace(R.id.detail_container, newFragment);
                    transaction.commit();
                } else {
                    Intent intent;
                    if (country.equals(view.getResources().getString(R.string.africa))) {
                        intent = new Intent(getActivity(), AfricaActivity.class);
                    } else if (country.equals(view.getResources().getString(R.string.asia))) {
                        intent = new Intent(getActivity(), AsiaActivity.class);
                    } else if (country.equals(view.getResources().getString(R.string.europe))) {
                        intent = new Intent(getActivity(), EuropeActivity.class);
                    } else {
                        intent = new Intent(getActivity(), AfricaActivity.class);
                    }
                    startActivity(intent);
                }
            }
    

    You could also do the comparisons using Raghav's suggestion for switch statement with strings.