Java 为不同的列表视图项选择不同的颜色
我有以下要求:Java 为不同的列表视图项选择不同的颜色,java,android,listview,user-interface,Java,Android,Listview,User Interface,我有以下要求: 不同列表视图项的不同颜色 在代码中动态指定颜色 仅当按下/选择列表视图项时,才应显示颜色 列表视图项的颜色不应永久更改 不管出于什么原因,它似乎不像我想的那样直截了当。唯一朝着正确方向发展的解决方案是: 需要注意的是,这不会更改on select颜色,而是永久性地更改背景颜色,并且如果向下滚动一点,它已经更改列表视图项目的背景颜色 我怎样才能做到这一点?我建议采用以下方法: 您需要创建一个支持多个不同项目的列表视图适配器 每个不同的Item类表示不同的颜色,可以有自己的实现
- 不同列表视图项的不同颜色
- 在代码中动态指定颜色
- 仅当按下/选择列表视图项时,才应显示颜色
- 列表视图项的颜色不应永久更改
我怎样才能做到这一点?我建议采用以下方法:
- 您需要创建一个支持多个不同项目的
列表视图
适配器
- 每个不同的Item类表示不同的颜色,可以有自己的实现来处理按下或选定状态
- 因为每个
都有自己的.xml布局文件,所以您可以在那里指定所需的选择器ListItem
列表视图中的每个项继承自的基类
列表项
- 此类提供抽象方法来获取表示项及其类型的
视图
- 如果需要,
类可以有一个ListItem
字段mColor,该字段保存项目表示的颜色Integer
- 如果需要,
类可以有一个方法来设置具有特定颜色的选择器ListItem
public abstract class ListItem {
public static final int TYPE_WHATEVER_1 = 0;
public static final int TYPE_WHATEVER_2 = 1;
// and so on...
/** the total number of list-item-types */
public static final int TYPE_COUNT = typecounthere;
// if required for your implementation:
protected int mColor;
public abstract int getViewType();
public abstract View getView(LayoutInflater inflater, View convertView);
/** creates and sets the selector with your specified color */
public void setupSelectorColor() {
StateListDrawable states = new StateListDrawable();
ColorDrawable cdPressed = new ColorDrawable(mColor);
ColorDrawable cdSelected = new ColorDrawable(mColor);
ColorDrawable cdDefault = new ColorDrawable(Color.TRANSPARENT);
states.addState(new int[] {
android.R.attr.state_pressed
},
cdPressed);
states.addState(new int[] {
android.R.attr.state_selected
},
cdSelected);
states.addState(new int[] {},
cdDefault);
setBackgroundDrawable(states);
}
}
public class ItemTypeOne extends ListItem {
public ItemTypeOne(int color) {
mColor = color;
}
@Override
public int getViewType() {
// return the type
return TYPE_WHATEVER_1;
}
@Override
public View getView(LayoutInflater inflater, View convertView) {
if(convertView == null) {
// inflate the layout
convertView = inflater.inflate(R.layout.item_type_one, null);
}
// setup the selector
setupSelectorColor();
// do other stuff
return convertView;
}
}
public class ListItemAdapter extends ArrayAdapter<ListItem> {
public ListItemAdapter(Context context, List<ListItem> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getItem(position).getView(LayoutInflater.from(getContext()), convertView);
}
@Override
public int getItemViewType(int position) {
return getItem(position).getViewType();
}
@Override
public int getViewTypeCount() {
return ListItem.TYPE_COUNT;
}
}
- 对于每种颜色,创建一个子类
ListItem
- 在
方法中,膨胀所需的布局getView(…)
- 不要忘记在
方法中返回正确的类型getViewType()
- 你想在这里用你的颜色做什么都行
- 使用您的颜色设置选择器
public abstract class ListItem {
public static final int TYPE_WHATEVER_1 = 0;
public static final int TYPE_WHATEVER_2 = 1;
// and so on...
/** the total number of list-item-types */
public static final int TYPE_COUNT = typecounthere;
// if required for your implementation:
protected int mColor;
public abstract int getViewType();
public abstract View getView(LayoutInflater inflater, View convertView);
/** creates and sets the selector with your specified color */
public void setupSelectorColor() {
StateListDrawable states = new StateListDrawable();
ColorDrawable cdPressed = new ColorDrawable(mColor);
ColorDrawable cdSelected = new ColorDrawable(mColor);
ColorDrawable cdDefault = new ColorDrawable(Color.TRANSPARENT);
states.addState(new int[] {
android.R.attr.state_pressed
},
cdPressed);
states.addState(new int[] {
android.R.attr.state_selected
},
cdSelected);
states.addState(new int[] {},
cdDefault);
setBackgroundDrawable(states);
}
}
public class ItemTypeOne extends ListItem {
public ItemTypeOne(int color) {
mColor = color;
}
@Override
public int getViewType() {
// return the type
return TYPE_WHATEVER_1;
}
@Override
public View getView(LayoutInflater inflater, View convertView) {
if(convertView == null) {
// inflate the layout
convertView = inflater.inflate(R.layout.item_type_one, null);
}
// setup the selector
setupSelectorColor();
// do other stuff
return convertView;
}
}
public class ListItemAdapter extends ArrayAdapter<ListItem> {
public ListItemAdapter(Context context, List<ListItem> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getItem(position).getView(LayoutInflater.from(getContext()), convertView);
}
@Override
public int getItemViewType(int position) {
return getItem(position).getViewType();
}
@Override
public int getViewTypeCount() {
return ListItem.TYPE_COUNT;
}
}
- 支持不同项类型的适配器
public abstract class ListItem {
public static final int TYPE_WHATEVER_1 = 0;
public static final int TYPE_WHATEVER_2 = 1;
// and so on...
/** the total number of list-item-types */
public static final int TYPE_COUNT = typecounthere;
// if required for your implementation:
protected int mColor;
public abstract int getViewType();
public abstract View getView(LayoutInflater inflater, View convertView);
/** creates and sets the selector with your specified color */
public void setupSelectorColor() {
StateListDrawable states = new StateListDrawable();
ColorDrawable cdPressed = new ColorDrawable(mColor);
ColorDrawable cdSelected = new ColorDrawable(mColor);
ColorDrawable cdDefault = new ColorDrawable(Color.TRANSPARENT);
states.addState(new int[] {
android.R.attr.state_pressed
},
cdPressed);
states.addState(new int[] {
android.R.attr.state_selected
},
cdSelected);
states.addState(new int[] {},
cdDefault);
setBackgroundDrawable(states);
}
}
public class ItemTypeOne extends ListItem {
public ItemTypeOne(int color) {
mColor = color;
}
@Override
public int getViewType() {
// return the type
return TYPE_WHATEVER_1;
}
@Override
public View getView(LayoutInflater inflater, View convertView) {
if(convertView == null) {
// inflate the layout
convertView = inflater.inflate(R.layout.item_type_one, null);
}
// setup the selector
setupSelectorColor();
// do other stuff
return convertView;
}
}
public class ListItemAdapter extends ArrayAdapter<ListItem> {
public ListItemAdapter(Context context, List<ListItem> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getItem(position).getView(LayoutInflater.from(getContext()), convertView);
}
@Override
public int getItemViewType(int position) {
return getItem(position).getViewType();
}
@Override
public int getViewTypeCount() {
return ListItem.TYPE_COUNT;
}
}
公共类ListItemAdapter扩展了ArrayAdapter{
公共ListItemAdapter(上下文、列表对象){
超级(上下文,0,对象);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
返回getItem(position).getView(LayoutInflater.from(getContext()),convertView);
}
@凌驾
public int getItemViewType(int位置){
返回getItem(position).getViewType();
}
@凌驾
public int getViewTypeCount(){
返回ListItem.TYPE\u计数;
}
}
总而言之:
ArrayList<ListItem> list = new ArrayList<ListItem>();
// fill the list
list.add(new ItemTypeOne(somecolor));
list.add(new ItemTypeTwo(somecolor));
list.add(new ItemTypeOne(somecolor));
list.add(new ItemTypeWhatever(somecolor));
ListView lv = (ListView) v.findViewById(R.id.listView1);
ListItemAdapter a = new ListItemAdapter(Context, list);
lv.setAdapter(a);
ArrayList list=new ArrayList();
//填写清单
添加(新的ItemTypeOne(somecolor));
添加(新的ItemTypeTwo(somecolor));
添加(新的ItemTypeOne(somecolor));
添加(新的ItemTypeWhatever(somecolor));
ListView lv=(ListView)v.findViewById(R.id.listView1);
ListItemAdapter a=新的ListItemAdapter(上下文,列表);
低压设置适配器(a);
关于
自定义视图
和选择器及其行为,我建议阅读此问题(并回答):我要说的是,不要将其过分复杂化。它可以简单地创建一个包含可能颜色的int
数组,并使用Random
类将它们设置为每个项目
// This goes inside hosting fragment or activity
listview.setOnItemClickListner( new OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
if(view.isSelected()){
view.setSelected(false);
// also maybe change bg color back to normal?
}
else {
// This one for always a different color
view.setBackgroundColor(adapter.getColor());
// This is for foreground color change instead of background
FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.my_frame_layout);
final Drawable drawable = new ColorDrawable( /* your getColor() function */ );
frameLayout.setForeground(drawable);
// This one for alwyas the same color for the row at position given by {@param position}
view.setBackgroundColor(adapter.getColor(position));
view.setSelected(true);
}
}
});
// All this goes inside your custom listview Adapter
int[] colors = {
R.colors.red,
R.colors.blue,
...
}
Random random = new Random();
// If each time the selection will bring a different color, use this implementation
public int getColor() {
return colors[random.nextInt(colors.length)];
}
// If each row should have different color, but always the same color for a row then use this one instead
SparseIntArray spa = new SparseIntArray();
public int getColor(int position) {
if(spa.get(position) == 0) {
// the color hasnt been created for that row yet
spa.put(position, colors[random.nextInt(colors.length)];
}
return spa.get(position);
}
**编辑:**现在,如果您想要的是前景选择,那么您的行应该有一个FrameLayout
容器,并且您应该更改它的“安卓:前景”属性:
final Drawable drawable = new ColorDrawable( /* your getColor() function */ );
frameLayout.setForeground(drawable);
我得说跟我一起去。为单个ListView的背景颜色创建一个状态感知的可绘制XML文件。下面是一个名为background_black.xml和background_green.xml的状态感知可绘制文件的示例。它们使默认背景色变为白色,并在按下/选择时将其临时更改为黑色或绿色。这两个文件都放在您的Drawable文件夹中
background\u black.xml
background\u green.xml
在ListView项xml文件中,为根布局或提供可见背景色的任何元素指定一个ID。对于这个例子,我假设它是您的根布局。然后在适配器的getView()中,抓取已为其分配id的元素,并将您创建的其中一个可绘制项设置为所需的背景颜色。像这样:
@Override
public View getView(int position, View convertView, ViewGroup parent){
//inflate your convertView, etc...
...
ViewGroup baseLayout = (ViewGroup)convertView.findViewById(R.id.<your base layout id>);
//these conditions need to reflect how you decide which list item gets which color
if(position % 2 == 0){
baseLayout.setBackground(R.drawable.background_black);
} else {
baseLayout.setBackground(R.drawable.background_green);
//do whatever else you need
...
return convertView;
}
@覆盖
公共视图getView(int位置、视图转换视图、视图组父视图){
//膨胀你的视野,等等。。。
...
ViewGroup baseLayout=(ViewGroup)convertView.findViewById(R.id.);
//这些条件需要反映您如何决定哪个列表项获得哪个颜色
如果(位置%2==0){
底座布局。立根台(右拉深。背景为黑色);
}否则{
基础布局。立根背景(右侧可拉深。背景为绿色);
//你还需要什么就做什么
...
返回视图;
}
注意:setBackground()是一个新函数,如果为旧版本的Android编码,请使用setBackgroundDrawable()。这里的困难在于按下/选中的颜色是动态的。您不能使用静态xml颜色状态列表。但您可以通过代码创建。下面是如何做到这一点 您只需实现ListAdapter:
private class MyListAdapter implements ListAdapter{
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView!=null){
CheckedTextView textView = (CheckedTextView)convertView;
textView.setText("the text for item "+position);
textView.setTextColor(makeColorStateListForItem(position));
return textView;
}else{
CheckedTextView textView = new CheckedTextView(parent.getContext());
textView.setText("the text for item "+position);
textView.setTextColor(makeColorStateListForItem(position));
return textView;
}
}
private ColorStateList makeColorStateListForItem(int position){
int pressedColor = pressedColorForItem(position);
int checkedColor = checkedColorForItem(position);
int defaultColor = defaultColorForItem(position);
ColorStateList colorStateList = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_pressed},
new int[]{android.R.attr.state_checked},
new int[]{0},
},
new int[]{
pressedColor, //use when state is pressed
checkedColor, //use when state is checked, but not pressed
defaultColor}); //used when state is not pressed, nor checked
}
private int pressedColorForItem(int position){
//write your business logic to determine color here
return ...;
}
private int checkedColorForItem(int position){
//write your business logic to determine color here
return ...;
}
private int defaultColorForItem(int position){
return Color.WHITE;
}
//all other adapter methods
//...
请注意,使用选中的android.R.attr.state\u
而不是更直观的android.R.attr.state\u选择的,因为state\u selected
不是用触摸屏非常精确地定义的(即,state\u selected可以在模拟器上给出预期的行为,但在真实设备上可能会失败)
另一方面,state\u checked
+将在模拟器和真实设备上正常工作
什么时候打电话