我正在使用一个列表视图绑定一些项目,点击后我想更新列表视图的视图但是当我滚动它时,该效果应用于其他视图,如果滚动更多时间,它会随机改变位置。
这是我的代码。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/twvTest"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</LinearLayout>
public class MainActivity extends Activity {
ListView twvTest;
ArrayList<DataModel> dataModels;
NameListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
twvTest = (ListView) findViewById(R.id.twvTest);
dataModels = new ArrayList<>();
adapter = new NameListAdapter(MainActivity.this, dataModels);
twvTest.setAdapter(adapter);
twvTest.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i < twvTest.getCount(); i++) {
TextView txtName = (TextView) view.findViewById(R.id.txtName);
if (i == position) {
txtName.setTextColor(Color.GREEN);
txtName.setBackgroundColor(Color.YELLOW);
} else {
txtName.setTextColor(Color.YELLOW);
txtName.setBackgroundColor(Color.GREEN);
}
}
}
});
fillList();
}
private void fillList() {
for (int i = 0; i < 30; i++) {
DataModel dataModel = new DataModel();
dataModel.setName("Name : " + i);
dataModels.add(dataModel);
}
adapter.notifyDataSetChanged();
}
}
public class NameListAdapter extends BaseAdapter {
Context context;
ArrayList<DataModel> dataModels;
LayoutInflater inflater;
public NameListAdapter(Context context, ArrayList<DataModel> dataModels) {
this.context = context;
this.dataModels = dataModels;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return dataModels.size();
}
@Override
public Object getItem(int position) {
return dataModels.get(position);
}
@Override
public long getItemId(int position) {
return dataModels.indexOf(getItem(position));
}
private class Holder {
TextView txtName;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
holder = new Holder();
convertView = inflater.inflate(R.layout.test_adapter_raw, parent, false);
holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.txtName.setText(dataModels.get(position).getName());
return convertView;
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#ffffff"
android:orientation="vertical">
<TextView
android:id="@+id/txtName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#949494"
android:gravity="center"
android:text="Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff"
android:textStyle="bold" />
</LinearLayout>
public class DataModel {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
答案 0 :(得分:0)
您无法在onClick()
期间直接更改视图,因为该视图已重新使用....
因此,您更改了视图的颜色,该视图可能会在另一个位置重新使用,然后,另一个位置将显示彩色视图。
您必须控制适配器中的视图颜色。这样,您的Activity仅更新Adapter并调用notifyDataSetChanged()
以使ListView更新内容。
您的活动代码
twvTest.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Inform the adapter that following item should be displayed in Yellow
adapter.displayViewInYellow(position);
adapter.notifyDataSetChanged();
}
});
您的适配器代码
public class NameListAdapter extends BaseAdapter {
boolean [] arrayOfViewsThatMustShowYellow;
public NameListAdapter(Context context, ArrayList<DataModel> dataModels) {
...
arrayOfViewsThatMustShowYellow = new boolean[getCount()];
}
public void displayViewInYellow(int position) {
// boolean array to track view that must be displayed in Yellow
arrayOfViewsThatMustShowYellow[position] = true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
.....
// Following code could be simplified to convertView.setEnabled(arrayOfViewsThatMustShowYellow[position])
if(arrayOfViewsThatMustShowYellow[position] == true) {
holder.txtName.setTextColor(Color.GREEN);
holder.txtName.setBackgroundColor(Color.YELLOW);
} else {
holder.txtName.setTextColor(Color.YELLOW);
holder.txtName.setBackgroundColor(Color.GREEN);
}
}
}
注意强>
这是一个例子......只是分享关于如何做到这一点的想法...... 请记住,如果需要更新任何视图,则需要在适配器内跟踪此更改(并且永远不要在外部 - 例如在ClickListeners或Activity中)。
答案 1 :(得分:0)
如果名称为空值,则视图持有者将为it.set&#34;&#34;设置ramdom值。对于空名可能适合它。
答案 2 :(得分:0)
这是因为ListView重新审视你的观点。因此,您使用相同的视图用于其他位置。为避免混乱,请在适配器内设置一个clicklistener并处理Holder内的颜色。
public class NameListAdapter extends BaseAdapter {
Context context;
ArrayList<DataModel> dataModels;
LayoutInflater inflater;
public NameListAdapter(Context context, ArrayList<DataModel> dataModels) {
this.context = context;
this.dataModels = dataModels;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return dataModels.size();
}
@Override
public Object getItem(int position) {
return dataModels.get(position);
}
@Override
public long getItemId(int position) {
return dataModels.indexOf(getItem(position));
}
private class Holder {
TextView txtName;
LinearLayout root_layout;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
holder = new Holder();
convertView = inflater.inflate(R.layout.test_adapter_raw, parent, false);
holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
holder.root_layout=(LinearLayout)convertView.findViewById(R.id.root_layout)
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.txtName.setText(dataModels.get(position).getName());
holder.root_layout.setOnClickListener(new View.OnClickListener(){
holder.txtName.setTextColor(Color.GREEN);
holder.txtName.setBackgroundColor(Color.YELLOW);
//implement your own logic to remove color on second click
});
return convertView;
}
}
为Listitems根布局使用Id,如下所示
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#ffffff"
android:orientation="vertical">
<TextView
android:id="@+id/txtName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#949494"
android:gravity="center"
android:text="Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff"
android:textStyle="bold" />
</LinearLayout>