在Android导航抽屉中添加图标?

17

我已经在网络上搜索了很久,但似乎无法找到答案,即使在官方的Android文档中也是如此。

我正在创建一个应用程序,实现Android的新导航抽屉布局。该布局的文档可以在这里这里找到。

在设计文档以及一些流行的应用程序(如Facebook和Google Currents)中,抽屉项前面有图标。

设计文档本身提到了它们,在“导航抽屉的内容”下

导航目标可以具有可选的前导图标以及尾部计数器。使用计数器通知用户有关相应视图中数据状态的更改。

不幸的是,开发者文档没有提到如何在此设置中实现图标。它描述了如何实现项目列表:

public class MainActivity extends Activity {
private String[] mPlanetTitles;
private ListView mDrawerList;
...

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mPlanetTitles = getResources().getStringArray(R.array.planets_array);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);

    // Set the adapter for the list view
    mDrawerList.setAdapter(new ArrayAdapter<String>(this,
            R.layout.drawer_list_item, mPlanetTitles));
    // Set the list's click listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    ...
}
}
因为它们的实现使用了getStringArray(),所以我无法想到一种方法来修改行项目的xml以包含图标。
这令人困惑,因为许多应用程序似乎可以很好地在每个文本项之前实现图标,并且设计文档甚至提到了添加图标。我觉得一定有一些简单的API调用来实现添加这些图标,但到目前为止,我找到的唯一实现方式似乎过于复杂了。
有人知道如何将图标添加到导航抽屉项吗?是否有一种使用简单API调用的方法可以做到这一点,或者所有这些公司(Facebook、Google等)都不得不寻找解决该问题的方法?
谢谢大家。

你最终解决了这个问题吗?如果是的话,能否分享一下? - Jonny Wright
4个回答

7
因为它们的实现使用getStringArray(),所以我想不出任何方法来修改行项目的xml以包括图标。 ListAdapter的模型数据选择对于该ListAdapter创建的行是否可以具有图标没有任何影响。
有人知道如何向导航抽屉项目添加图标吗?
在您的ListAdapter行布局中放置一个ImageView。通过您的ListAdapter填充那个ImageView,例如通过覆盖ArrayAdaptergetView()。换句话说,您可以像多年来一样处理其他任何ListView
是否有一种简单的API调用方法来完成这个操作,这取决于您对"简单"和"API调用"的定义。

3
创建一个适配器类,例如...
public class AdapterClass  extends ArrayAdapter<String> {
Context context;
private ArrayList<String> TextValue = new ArrayList<String>();

public AdapterClass(Context context, ArrayList<String> TextValue) {
    super(context, R.layout.row_of_drawer, TextValue);
    this.context = context;
    this.TextValue= TextValue;

}


@Override
public View getView(int position, View coverView, ViewGroup parent) {
    // TODO Auto-generated method stub

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.row_of_drawer,
            parent, false);

    TextView text1 = (TextView)rowView.findViewById(R.id.text1);
    text1.setText(TextValue.get(position));

    return rowView;

}

}

请修改您的MainActivity并进行一些更改。

使用

   AdapterClass adClass = new AdapterClass(MainActivity.this, name_of_arrayList);

    mDrawerList.setAdapter(adClass);

代替

 mDrawerList.setAdapter(new ArrayAdapter<String>(this,
        R.layout.drawer_list_item, mPlanetTitles));

2
字符串数组并不是行的定义布局。你的R.layout.drawer_list_item代表列表中每一行的布局。如果你想要包含一个图片(或者其他复杂的行布局),你需要将这个图片视图包含到自定义布局xml中,替换掉R.layout.drawer_list_item的xml。
至于如何将图片或文本设置到不同的行中,这都是在数组适配器的getView()方法中完成的。一个简单的例子如下(假设在行中有一个textview和imageview):
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.revise_listview, parent,false);

    TextView tv = (TextView)convertView.findViewById(R.id.text);
    ImageView iv = (ImageView)convertView.findViewById(R.id.image);

    tv1.setText(stringArray.get(i));
    if(//condition) {
        iv.setImageResource(R.drawable.imagexx);
    }
    return convertView;
}

实现每一行视图的更高效方式是使用viewholder模式。你可以在这里找到许多示例。


2
为了更加清晰地构建这个项目,我增加了一些代码行来实现面向对象的实现方式,它可以从一个包含NavigationItem数组的类中生成菜单项的所有内容。这个类是一个简单的Java类,包含一个用于菜单项文本、图标和片段的字段。
在MainActivity中,我的导航栏仅通过该数组进行定义:
NavigationAdapter navigationMenuAdapter;
NavigationItem[] navigationMenuItems = {
    new NavigationItem(R.string.menu_home, R.drawable.ic_menu_home, new MainFragment()),
    new NavigationItem(R.string.menu_statistics, R.drawable.ic_statistics, new StatisticsFragment()),
    new NavigationItem(R.string.menu_settings, R.drawable.ic_settings, new SettingsFragment()),
};

protected void onCreate(Bundle savedInstanceState) {
    ...
    navigationMenuAdapter = new NavigationAdapter(this, navigationMenuItems);
    mDrawerList.setAdapter(navigationMenuAdapter);
}

...
private void selectItem(int position) {
    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
                   .replace(R.id.content_frame, navigationMenuItems[position].fragment)
                   .commit();

    mDrawerList.setItemChecked(position, true);
    setTitle(navigationMenuItems[position].stringTitle);
    mDrawerLayout.closeDrawer(mDrawerList);
}

NavigationItem类:

public class NavigationItem
{
    /**
     * 
     * @param stringTitle The id of the string resource of the text of the item.
     * @param drawableIcon The id of the drawable resource of icon of the item.
     * @param fragment The Fragment to be loaded upon selecting the item.
     */
    public NavigationItem(int stringTitle, int drawableIcon, Fragment fragment)
    {
        this.stringTitle = stringTitle;
        this.drawableIcon = drawableIcon;
        this.fragment = fragment;
    }

    /**
     * The id of the string resource of the text of the item.
     */
    public int stringTitle;

    /**
     * The id of the drawable resource of icon of the item.
     */
    public int drawableIcon;

    /**
     * The Fragment to be loaded upon selecting the item.
     */
    public Fragment fragment;
}

还有导航适配器:

public class NavigationAdapter extends BaseAdapter {
    private Context context;
    private NavigationItem[] navigationItems;

    public NavigationAdapter(Context context, NavigationItem[] items) {
        this.context = context;
        navigationItems = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.list_item_navigation, parent, false);
        } else {
            row = convertView;
        }

        TextView tvTitle = (TextView) row.findViewById(R.id.textView);
        ImageView ivIcon = (ImageView) row.findViewById(R.id.imageView);

        tvTitle.setText(navigationItems[position].stringTitle);
        ivIcon.setImageResource(navigationItems[position].drawableIcon);
        return row;
    }
}

这个使用非常基础的xml布局list_item_navigation,只包含一个ImageView和一个TextView


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接