Android 带光标的聊天气泡列表视图或适配器:滚动时位置错误

Android 带光标的聊天气泡列表视图或适配器:滚动时位置错误,android,android-listview,android-cursoradapter,Android,Android Listview,Android Cursoradapter,我正面临一个聊天布局的实现 我有一些数据来自sqlite DB,一个光标适配器和2个布局: -在右边显示数据的那个 -在左边显示数据的那个 正如您所见,布局只有两个区别:背景和方向(左、右)。如果消息是我的或来自我正在谈论的用户,我将以编程方式选择布局 这是列表视图行的两种布局 布局权: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="matc

我正面临一个聊天布局的实现

我有一些数据来自sqlite DB,一个光标适配器和2个布局: -在右边显示数据的那个 -在左边显示数据的那个

正如您所见,布局只有两个区别:背景和方向(左、右)。如果消息是我的或来自我正在谈论的用户,我将以编程方式选择布局

这是列表视图行的两种布局

布局权:

<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
    android:id="@+id/roomLisViewtMessageText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:background="@drawable/speech_bubble_green"
    android:layout_margin="5dip"
    android:textColor="#FFF"
    android:textSize="20sp" /></RelativeLayout>
因此,我在图1中有一个正常的行为,在向下滚动并返回顶部后,我会看到如图2所示的消息,并且每次滚动屏幕都会改变


怎么了???谢谢

将final添加到文本框或使用文本框的holder

将final添加到文本框或使用文本框的holder

在显示数据时,应使用一个视图显示左右消息,并更改bindView中的重力

现在您有了创建视图的方法newView,但当您滚动视图时,视图被重用(有时为橙色,有时为绿色)

删除newView metod并使bindView中的所有内容(使用一个视图)-将更加简单和干净;-)

我把它写在我的邮件列表上-更改线性布局的重力


但若您必须使用2视图,请使用getView来膨胀视图,但这样您就失去了高效的视图创建(重用)

您应该使用一个视图来显示左右消息,并在bindView中更改要显示的数据时的重力

现在您有了创建视图的方法newView,但当您滚动视图时,视图被重用(有时为橙色,有时为绿色)

删除newView metod并使bindView中的所有内容(使用一个视图)-将更加简单和干净;-)

我把它写在我的邮件列表上-更改线性布局的重力


但若您必须使用2视图,那个么就使用getView来扩展视图—但这样您就失去了高效的视图创建(重用)

我尝试了一种实现保持器模式,但还不能工作。正如我所知,在游标适配器中,holder模式是不必要的,我知道它有点不好,但它很奇怪……我尝试了一个实现holder模式,但还不起作用。正如我所知,在游标适配器中不需要holder模式,我知道有些东西不好,但很奇怪……我给你+1作为答案,但现在我无法测试你的提示,因为我用另一个不同的函数替换了这个函数。对不起,我给你+1作为答案,但现在我无法测试你的提示,因为我已经用另一个不同的函数替换了这个函数。很抱歉
<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
    android:id="@+id/roomLisViewtMessageText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:background="@drawable/speech_bubble_orange"
    android:layout_margin="5dip"
    android:textColor="#FFF"
    android:textSize="20sp" /></RelativeLayout>
public class MyCursorAdapter extends CursorAdapter {

private static final String tag = "ADAPTER";
private LayoutInflater layoutInflater;
private Context mContext;

public MyCursorAdapter (Context context, Cursor c, int flags) {
    super(context, c, flags);
    mContext = context;
    layoutInflater = LayoutInflater.from(context);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent){

    int isMine = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseHelper._IS_MINE));
    if(isMine==1) return layoutInflater.inflate(R.layout.room_list_view_left, parent, false);
    else return layoutInflater.inflate(R.layout.room_list_view_right, parent, false);
}

/**
 * @param view: The view in which the elements we set up here will be displayed.
 * @param context: The running context where this ListView adapter will be active.
 * @param cursor: The Cursor containing the query results we will display.
 */
@Override
public void bindView(View view, Context context, Cursor cursor) {

    Log.v(tag,"position---->"+cursor.getPosition());
    int isMine = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseHelper.IS_MINE));
    String mess = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.MESSAGE));

    TextView messText = (TextView) view.findViewById(R.id.myLisViewtMessageText);
    if (messText != null){
        if(isMine==1){
            Log.d(tag,"mess = "+mess+" isMine = "+isMine);
        }
        else{
            Log.d(tag,"mess = "+mess+" isMine = "+isMine);
        }
        messText.setText(mess);
    }
}