我有一个应用程序,我在其中显示具有两种不同布局的ListView。我在列表中有大约25个项目,初始项目按顺序显示所有内容,但是当我向下滚动时,特定行中的某些项目会相互覆盖,每次滚动时它们都会以与前一个不同的方式显示。图像也会被洗牌并相互覆盖。
这是我的自定义适配器类: -
public class CustomAdapterSettings extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
private ArrayList<String> arrListData = new ArrayList<String>();
private ArrayList<String> arrListDescription = new ArrayList<String>();
private LayoutInflater layInflater;
private Context context;
private TreeSet<Integer> treeSeparatorsSet = new TreeSet<Integer>();
public CustomAdapterSettings(Context context) {
this.context = context;
layInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final String data, final String description) {
arrListData.add(data);
arrListDescription.add(description);
notifyDataSetChanged();
}
public void addSeparatorItem(final String seperator) {
arrListData.add(seperator);
arrListDescription.add(seperator);
// save separator position
treeSeparatorsSet.add(arrListData.size() - 1);
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
return treeSeparatorsSet.contains(position) ? TYPE_SEPARATOR
: TYPE_ITEM;
}
@Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
@Override
public int getCount() {
return arrListData.size();
}
@Override
public String getItem(int position) {
return arrListData.get(position);
}
public String getItemDescription(int position) {
return arrListDescription.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private static class ViewHolder {
public TextView tvSettingsTagSeper;
public TextView tvSettingsDescription;
public CheckBox cbSettings;
public ImageView ivSettings;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
int type;
type = getItemViewType(position);
System.out.println("getView " + position + " " + convertView
+ " type = " + type);
if (convertView == null) {
viewHolder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = layInflater.inflate(
R.layout.layout_settings_list, null);
viewHolder.tvSettingsTagSeper = (TextView) convertView
.findViewById(R.id.tvSettingsTag);
viewHolder.tvSettingsDescription = (TextView) convertView
.findViewById(R.id.tvSettingsDescription);
viewHolder.cbSettings = (CheckBox) convertView
.findViewById(R.id.cbSettings);
viewHolder.ivSettings = (ImageView) convertView
.findViewById(R.id.ivSettings);
break;
case TYPE_SEPARATOR:
convertView = layInflater.inflate(R.layout.layout_seperator,
null);
viewHolder.tvSettingsTagSeper = (TextView) convertView
.findViewById(R.id.tvSeperator);
break;
}
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (type == 0) {
viewHolder.tvSettingsTagSeper.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
(int) (ScreenCalculationActivity.heightScreen * 0.035));
viewHolder.tvSettingsTagSeper.setPadding(0,
(int) (ScreenCalculationActivity.heightScreen * 0.01),
(int) (ScreenCalculationActivity.widthScreen * 0.15), 0);
viewHolder.tvSettingsDescription.setPadding(0,
(int) (ScreenCalculationActivity.heightScreen * 0.001),
(int) (ScreenCalculationActivity.widthScreen * 0.15), 0);
RelativeLayout.LayoutParams layParams = (RelativeLayout.LayoutParams) viewHolder.ivSettings
.getLayoutParams();
layParams.setMargins(0, 0,
(int) (ScreenCalculationActivity.widthScreen * 0.045), 0);
viewHolder.ivSettings.getLayoutParams().height = (int) (ScreenCalculationActivity.heightScreen * 0.06);
viewHolder.ivSettings.getLayoutParams().width = (int) (ScreenCalculationActivity.heightScreen * 0.06);
viewHolder.ivSettings.setLayoutParams(layParams);
layParams = (RelativeLayout.LayoutParams) viewHolder.cbSettings
.getLayoutParams();
layParams.setMargins(0, 0,
(int) (ScreenCalculationActivity.widthScreen * 0.03), 0);
viewHolder.cbSettings.setLayoutParams(layParams);
layParams = (RelativeLayout.LayoutParams) viewHolder.tvSettingsTagSeper
.getLayoutParams();
layParams.setMargins(
(int) (ScreenCalculationActivity.widthScreen * 0.05), 0, 0,
0);
viewHolder.tvSettingsTagSeper.setLayoutParams(layParams);
layParams = (RelativeLayout.LayoutParams) viewHolder.tvSettingsDescription
.getLayoutParams();
layParams.setMargins(
(int) (ScreenCalculationActivity.widthScreen * 0.05), 0, 0,
0);
viewHolder.tvSettingsDescription.setLayoutParams(layParams);
} else {
RelativeLayout.LayoutParams layParams = (RelativeLayout.LayoutParams) viewHolder.tvSettingsTagSeper
.getLayoutParams();
layParams.setMargins(
(int) (ScreenCalculationActivity.widthScreen * 0.02), 0, 0,
0);
viewHolder.tvSettingsTagSeper.setLayoutParams(layParams);
}
if (type == 0) {
if (position == 1 || position == 2 || position == 3
|| position == 6 || position == 9 || position == 10
|| position == 12 || position == 14 || position == 16
|| position == 18 || position == 22) {
viewHolder.ivSettings.setVisibility(View.VISIBLE);
} else {
viewHolder.cbSettings.setVisibility(View.VISIBLE);
}
viewHolder.cbSettings.setFocusable(false);
viewHolder.cbSettings.setFocusableInTouchMode(false);
viewHolder.ivSettings.setFocusable(false);
viewHolder.ivSettings.setFocusableInTouchMode(false);
if (arrListDescription.get(position) == null) {
RelativeLayout.LayoutParams layParams = (RelativeLayout.LayoutParams) viewHolder.tvSettingsTagSeper
.getLayoutParams();
layParams.addRule(RelativeLayout.CENTER_VERTICAL);
viewHolder.tvSettingsTagSeper.setLayoutParams(layParams);
}
viewHolder.tvSettingsTagSeper.setText(arrListData.get(position));
viewHolder.tvSettingsDescription.setText(arrListDescription
.get(position));
} else {
viewHolder.tvSettingsTagSeper.setText(arrListData.get(position));
}
return convertView;
}
}
这是我的布局layout_settings_list: -
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relLaySettings"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/tvSettingsTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="@color/White"
android:textStyle="bold"
android:typeface="monospace" />
<TextView
android:id="@+id/tvSettingsDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvSettingsTag"
android:textColor="@color/LightGrey" />
<CheckBox
android:id="@+id/cbSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:visibility="gone" />
<ImageView
android:id="@+id/ivSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/dropdown2"
android:visibility="gone" />
这是我的布局layout_seperator: -
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/LightGrey"
android:clickable="false">
<TextView
android:id="@+id/tvSeperator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textStyle="bold"
android:textColor="@color/Black" />
答案 0 :(得分:1)
我没有看到问题的确切来源,但我看到了一些可能导致您看到的小问题。
适配器的目的是将对象列表转换为屏幕中的视图列表。拥有多个包含数据的列表对我来说似乎不对。它不应该导致实际问题,但它可能会使你的心理表现更难。
您应该拥有封装您将在视图中反映的属性的对象:
public class Item {
}
public class DataItem extends Item {
String data;
String description;
}
public class SeparatorItem extends Item {
String description;
}
而不是2个列表和1个集合,您只有一个列表:
ArrayList<Item> list;
然后你可以将你的项目类型基于项目的实际类别(而不是使用一组索引):
@Override
public int getItemViewType(int position) {
Item item = list.get(position);
if (item instanceof DataItem)
return TYPE_ITEM;
else
return TYPE_SEPARATOR;
}
if
声明if (position == 1 || position == 2 || position == 3
|| position == 6 || position == 9 || position == 10
|| position == 12 || position == 14 || position == 16
|| position == 18 || position == 22) {
viewHolder.ivSettings.setVisibility(View.VISIBLE);
} else {
viewHolder.cbSettings.setVisibility(View.VISIBLE);
}
这个if
的两个问题:
Item
)中应该有一个字段,表示应显示ivSettings
或cbSettings
(一个视图或另一个视图)的事实。setVisibility(View.VISIBLE)
,但在哪里将其他视图设为View.GONE
?它们未初始化,因此ivSettings
或cbSettings
(您不可见的那个)的可见性将是您convertView
的可见性。 建议更正if
:
Item item = list.get(position);
if (item.shouldDisplayIvSettings()) {
viewHolder.ivSettings.setVisibility(View.VISIBLE);
viewHolder.cbSettings.setVisibility(View.GONE);
} else {
viewHolder.ivSettings.setVisibility(View.GONE);
viewHolder.cbSettings.setVisibility(View.VISIBLE);
}
当您为元素类型声明常量时,你已经正确了:
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
但是你不使用常量,而是使用if
中的整数文字:
if (type == 0) {
这并不多,但在代码发展时可能会导致错误。它应该用适当的常量代替:
if (type == TYPE_ITEM) {