我已经在网上搜索了这个问题的答案,但似乎找不到,即使在官方的Android文档中也是如此。
我正在创建一个实现Android新导航抽屉布局的应用程序。可以在here和here找到此布局的文档。
在设计文档以及Facebook和Google Currents等众多热门应用中,抽屉物品前面都有图标。
设计文档本身在“导航抽屉的内容”
下提及它们导航目标可以包含可选的前导图标以及尾随计数器。使用计数器通知用户相应视图中数据的更改状态。
不幸的是,Developer文档没有提到如何在此设置中实现图标。它描述了如何实现项目列表:
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,谷歌等)必须找到解决这个问题的方法?
谢谢大家。
答案 0 :(得分:7)
因为他们的实现使用getStringArray(),所以我无法想到修改行项目的xml以包含图标。
选择ListAdapter
的模型数据对ListAdapter
创建的行是否可以包含图标没有任何影响。
有谁知道如何在导航抽屉项目中添加图标?
在ImageView
的行布局中添加ListAdapter
。通过ImageView
填充ListAdapter
,例如覆盖getView()
上的ArrayAdapter
。 IOW,你就像对待任何其他ListView
一样,就像多年来一样。
有没有办法通过简单的API调用来执行此操作
这取决于您对“简单”和“API调用”的定义。
答案 1 :(得分:4)
创建一个类似..
的适配器类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);
insted of
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPlanetTitles));
答案 2 :(得分:2)
字符串数组不是行的定义布局。您的R.layout.drawer_list_item
表示列表中每行的布局。如果要包含图像(甚至是其他复杂的行布局),则将图像视图包含在替换R.layout.drawer_list_item
xml的自定义布局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;
}
实现每行视图的更有效方法是使用视图模式。您可以找到的例子之一是here。
答案 3 :(得分: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;
}
和NavigationAdapter:
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
。