根据字符串名称而不是列表视图项位置替换片段并启动活动

Posted

技术标签:

【中文标题】根据字符串名称而不是列表视图项位置替换片段并启动活动【英文标题】:Replace fragments and start actives based on string name instead of list view item position 【发布时间】:2015-09-27 00:15:21 【问题描述】:

根据我的列表视图,如何使用特定片段替换详细信息容器或根据所选项目的字符串名称而不是项目在列表中的位置启动特定活动?我正在寻找类似case string 而不是case 0case 1case 2 等的东西。初始但不正确的代码建议下的代码与我正在寻找的类似但不是正确的解决方案。我们将不胜感激。

字符串

<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();
            
        
    

初始但不正确的代码建议

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"));
                
            
        );

【问题讨论】:

【参考方案1】:

您要做的是从父级获取适配器,然后从适配器获取国家/地区名称。

试试这个:

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

您也可以使用 Raghav 对带有字符串的 switch 语句的建议进行比较。

【讨论】:

如果有编译错误,请见谅,没有IDE,我在编码方面毫无用处:) 当 mTwoPane 为 false 时开始一个活动怎么办?我也需要那个代码。我知道它是else ...,其中省略号被该代码替换。 我以为你能弄明白,因为它本质上就像第一部分中的代码。无论如何,我更新了我的答案。干杯

以上是关于根据字符串名称而不是列表视图项位置替换片段并启动活动的主要内容,如果未能解决你的问题,请参考以下文章

Android,从其他片段返回的空列表视图

基于String Array项,向下一个片段显示相同的项

Android 的 ArrayAdapter - 添加字符串列表视图而不是替换

将数据从片段列表视图项传递到活动字符串变量 onitemclicklistener

使用导航架构组件添加(而不是替换)片段

未分配给列表视图项的字符串