ListView在滚动后显示随机播放的图像

时间:2014-04-23 19:07:51

标签: android listview android-listview

我有一个应用程序,我在其中显示具有两种不同布局的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" />

1 个答案:

答案 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)中应该有一个字段,表示应显示ivSettingscbSettings(一个视图或另一个视图)的事实。
  • 您使用setVisibility(View.VISIBLE),但在哪里将其他视图设为View.GONE?它们未初始化,因此ivSettingscbSettings(您不可见的那个)的可见性将是您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);
}

常量声明VS使用整数文字

当您为元素类型声明常量时,你已经正确了:

private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;

但是你不使用常量,而是使用if中的整数文字:

if (type == 0) {

这并不多,但在代码发展时可能会导致错误。它应该用适当的常量代替:

if (type == TYPE_ITEM) {