Android ArrayAdapter未正确转换视图

时间:2016-08-30 22:26:45

标签: android listview android-arrayadapter android-viewholder

我有ArrayAdapter的自定义ListView,它使用自定义行布局,在XML中单独定义。布局只有三个TextViews和一个ImageView,放在RelativeLayout中。为了提高性能,适配器使用ViewHolder系统(如here所述的系统)来转换现有视图而不是扩展新视图。在ArrayAdapter.getView()中,适配器应该加粗或解开第一个TextView,具体取决于布尔值。

当我第一次打开应用程序时,所有TextView都正确加粗或取消绑定。但是,如果我滚动到ListView的底部,然后滚动回到顶部,所有标题TextView都是粗体,即使它们不应该是。我认为它必须与转换已经大胆的现有视图有关,但我无法弄清楚它是什么。我已经使用Android Studio调试了应用程序,它运行就像我想的那样 - 当我向上滚动时,适配器在调试窗口中正确地加粗/解开东西,但它们在应用程序上似乎都是大胆的。

我注意到的一件事是,如果我将TextView的textStyle属性更改为“粗体”,则所有标题TextView都从一开始就是粗体,并且永远不会更改。只有当我删除textStyle或将其设置为“正常”时,TextView才会在开始时正常。

这是ArrayAdapter中的getView():

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    PostShell shell = postShellList.get(getCount() - 1 - position); //I stack my ListView backwards, so index 0 is at the bottom
    ViewHolder holder;
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.row_layout, parent, false);
        holder = new ViewHolder();
        holder.firstLine = (TextView) convertView.findViewById(R.id.firstLine);
        holder.secondLine = (TextView) convertView.findViewById(R.id.secondLine);
        holder.thirdLine = (TextView) convertView.findViewById(R.id.thirdLine);
        holder.image = (ImageView) convertView.findViewById(R.id.image);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.firstLine.setText(shell.postTitle);
    if (shell.unread) {
        holder.firstLine.setTypeface(holder.firstLine.getTypeface(), Typeface.BOLD);
    } else {
        holder.firstLine.setTypeface(holder.firstLine.getTypeface(), Typeface.NORMAL);
    }
    //convert other TextViews
}

我的ViewHolder类只是一个带有几个TextView和ImageView的静态类。

这是我正在使用的行布局代码的相关部分:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="88dp">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="84dp"
    android:paddingRight="16dp"
    android:paddingTop="6dp"
    android:id="@+id/firstLine"
    android:ellipsize="end"
    android:text="First"
    android:textStyle="normal"
    android:singleLine="true" />

<!-- other views -->

</RelativeLayout>

3 个答案:

答案 0 :(得分:1)

问题似乎是“unboldening”文本不适用于以下语句:

  

holder.firstLine.setTypeface(holder.firstLine.getTypeface(),Typeface.NORMAL);

以下代码段遗漏了holder.firstLine.getTypeface(),只使用了更简单的setTypeface()种类。为我工作。

if (shell.unread) {
    holder.firstLine.setTypeface(holder.firstLine.getTypeface(), Typeface.BOLD);
} else {
    holder.firstLine.setTypeface(Typeface.DEFAULT);
}

答案 1 :(得分:0)

PostShell shell = postShellList.get(getCount() - 1 - position); //I stack my ListView backwards, so index 0 is at the bottom

如果ListView要求特定位置的元素,你最好在该位置给它元素,否则会混淆。如果您想要更改列表中项目的顺序,请更改列表的顺序,不要试图欺骗ListView以不同的顺序呈现它。

答案 2 :(得分:0)

您应按正常顺序存储观看次数,并使用android:stackFromBottomsetStackFromBottom()