Android ArrayAdapter 未正确转换视图
Android ArrayAdapter not properly converting Views
我有一个 ListView
的自定义 ArrayAdapter
,它使用自定义行布局,在 XML 中单独定义。布局只是三个 TextViews
和一个 ImageView
,放在一起 RelativeLayout
。为了提高性能,适配器使用 ViewHolder 系统(如 here 所述)来转换现有视图,而不是扩充新视图。在 ArrayAdapter.getView()
中,适配器应该根据布尔值加粗或取消加粗第一个 TextView。
当我第一次打开应用程序时,所有 TextView 都正确地加粗或未加粗。但是,如果我滚动到 ListView 的底部,然后滚动回顶部,所有标题 TextView 都是粗体,即使它们不应该是粗体。我认为它一定与转换已经是粗体的现有视图有关,但我无法弄清楚它是什么。我已经使用 Android Studio 调试了该应用程序,它的运行就像我认为的那样——当我向上滚动时,适配器正确地 bolds/unbolds 调试 window 中的东西,但是他们在应用程序上似乎都很大胆。
我注意到的一件事是,如果我将 TextView 的 textStyle
属性更改为 "bold,",所有 TextView 的标题从一开始就是粗体,并且永远不会改变。只有当我删除 textStyle
或将其设置为 "normal" 时,TextViews 在开始时才正常。
这是 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 class 只是一个带有几个 TextView 和一个 ImageView 的静态 class。
下面是我正在使用的行布局代码的相关部分:
<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>
PostShell shell = postShellList.get(getCount() - 1 - position); //I stack my ListView backwards, so index 0 is at the bottom
如果 ListView
要求在特定位置的元素,你最好给它那个位置的元素,否则它会混淆。如果您想更改列表中项目的顺序,请更改列表的顺序,不要试图欺骗 ListView
以不同的顺序呈现它。
您应该按正常顺序存储视图并使用 android:stackFromBottom
or setStackFromBottom()
。
问题似乎是 "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);
}
我有一个 ListView
的自定义 ArrayAdapter
,它使用自定义行布局,在 XML 中单独定义。布局只是三个 TextViews
和一个 ImageView
,放在一起 RelativeLayout
。为了提高性能,适配器使用 ViewHolder 系统(如 here 所述)来转换现有视图,而不是扩充新视图。在 ArrayAdapter.getView()
中,适配器应该根据布尔值加粗或取消加粗第一个 TextView。
当我第一次打开应用程序时,所有 TextView 都正确地加粗或未加粗。但是,如果我滚动到 ListView 的底部,然后滚动回顶部,所有标题 TextView 都是粗体,即使它们不应该是粗体。我认为它一定与转换已经是粗体的现有视图有关,但我无法弄清楚它是什么。我已经使用 Android Studio 调试了该应用程序,它的运行就像我认为的那样——当我向上滚动时,适配器正确地 bolds/unbolds 调试 window 中的东西,但是他们在应用程序上似乎都很大胆。
我注意到的一件事是,如果我将 TextView 的 textStyle
属性更改为 "bold,",所有 TextView 的标题从一开始就是粗体,并且永远不会改变。只有当我删除 textStyle
或将其设置为 "normal" 时,TextViews 在开始时才正常。
这是 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 class 只是一个带有几个 TextView 和一个 ImageView 的静态 class。
下面是我正在使用的行布局代码的相关部分:
<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>
PostShell shell = postShellList.get(getCount() - 1 - position); //I stack my ListView backwards, so index 0 is at the bottom
如果 ListView
要求在特定位置的元素,你最好给它那个位置的元素,否则它会混淆。如果您想更改列表中项目的顺序,请更改列表的顺序,不要试图欺骗 ListView
以不同的顺序呈现它。
您应该按正常顺序存储视图并使用 android:stackFromBottom
or setStackFromBottom()
。
问题似乎是 "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);
}