ListView에서 레이아웃을 전환하기 위해 사용자 지정 SimpleCursorAdapter를 구현하려고하지만 스크롤하는 동안 매우 임의의 결과가 나타납니다.ListView가 스크롤 될 때 내 사용자 지정 SimpleCursorAdapter가 다른 결과를 반환하는 이유
여기 내 문제는 위아래로 스크롤하면 ListView가 겉으로보기에 무작위로 레이아웃이 섞여 있다는 것입니다. 예를 들어, 행은 처음에는 listview_item_row 레이아웃을 가질 수 있지만 화면을 스크롤 할 때 listview_item_reply_row로 바꿀 수 있습니다. newView의 작동 방식을 정말로 이해했다고 말할 수는 없습니다. 레이아웃 뷰에서 이미지를 숨길 지 여부를 결정하기 위해 bindView를 성공적으로 사용할 수 있었지만 새로운 뷰는 구현에 대해 나에게 어둡게 가려져 있고 목록 스크롤은 왜 그런 식으로 동작합니까?
제 목표는 x 개의 항목으로 구성된 목록을 만드는 것입니다. 항목이 회신 또는 새 메시지인지 여부에 따라 해당 행에 특정 레이아웃을로드하려고합니다. 행에 이미지가 있는지 여부에 따라 행 레이아웃에서 이미지 뷰를 표시하거나 숨기고 싶습니다.
코드에서 생략 한 것은 가져 오기 및 행 레이아웃입니다. 나는 이것을 v4 지원 패키지에서 Fragments와 SimpleCursorAdapter를 사용하여 구현하려고한다. ListFragment의 행 레이아웃은 시각적으로 다르지만 동일한 위젯을 포함합니다.
목록보기 레이아웃 :<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/text_feed_header_random"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:padding="4dp"
android:text="Allmänt"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#FFF" />
<!--
The frame layout is here since we will be showing either
the empty view or the list view.
-->
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/text_feed_header_random"
android:layout_above="@+id/footer" >
<!--
Here is the list. Since we are using a ListActivity, we
have to call it "@android:id/list" so ListActivity will
find it
-->
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false" />
<!-- Here is the view to show if the list is emtpy -->
<TextView
android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="No items."
android:textAppearance="?android:attr/textAppearanceMedium" />
</FrameLayout>
<LinearLayout
android:id="@+id/footer"
style="@android:style/ButtonBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<Button
android:id="@+id/button_random_post"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Gör ett inlägg!" />
<Button
android:id="@+id/button_random_refresh"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Refresh list!" />
</LinearLayout>
</RelativeLayout>
위의 레이아웃을 사용하는 압축 된 조각 다음 ListFragment가 연결하는
public class RandomFragment extends ListFragment implements LOG {
private DatabaseHelper mDbHelper;
private KarenfeedCursorAdapter mAdapter;
private Cursor mCursor;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "RANDOMFRAGMENT START!");
mDbHelper = new DatabaseHelper(getActivity());
mDbHelper.open();
mDbHelper.setTable(Posts.TABLE_RANDOM_POSTS);
//TODO: Replace SimpleCursorAdapter with a FragmentList instead...
mCursor = mDbHelper.getAllPostsSortedCursor();
String[] columns = { Posts.COLUMN_ID, Posts.COLUMN_CREATED, Posts.COLUMN_USER, Posts.COLUMN_COMMENT };
int[] to = { R.id.imageItemPhoto, R.id.textItemDate, R.id.textItemUser, R.id.textItemComment };
int flags = 0;
mAdapter = new FeedCursorAdapter(getActivity(), R.layout.listview_item_row, mCursor, columns, to, flags);
this.setListAdapter(mAdapter);
initFeedList(); // This call in the end executes mCursor = mDbHelper.getAllPostsSorted(); mAdapter.changeCursor(mCursor); mAdapter.notifyDataSetChanged();
}
}
SimpleCursorAdapter : 질문을 읽은 후
public class FeedCursorAdapter extends SimpleCursorAdapter implements LOG {
private Context mContext;
private int mLayout;
public FeedCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
// TODO Auto-generated constructor stub
mContext = context;
mLayout = layout;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View view;
int id = cursor.getInt(cursor.getColumnIndex(Posts.COLUMN_ID));
int parentId = cursor.getInt(cursor.getColumnIndex(Posts.COLUMN_PARENT_ID));
Log.d(TAG, "id: " +id+ " parentId: " +parentId);
int hasImage = cursor.getInt(cursor.getColumnIndex(Posts.COLUMN_IMAGE));
if(id == parentId) {
view = inflater.inflate(R.layout.listview_item_row, parent, false);
} else {
view = inflater.inflate(R.layout.listview_item_reply_row, parent, false);
}
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
Log.d(TAG, "bindView()");
int id = cursor.getInt(cursor.getColumnIndex(Posts.COLUMN_ID));
int parentId = cursor.getInt(cursor.getColumnIndex(Posts.COLUMN_PARENT_ID));
int hasImage = cursor.getInt(cursor.getColumnIndex(Posts.COLUMN_IMAGE));
String date = cursor.getString(cursor.getColumnIndex(Posts.COLUMN_CREATED));
String user = cursor.getString(cursor.getColumnIndex(Posts.COLUMN_USER));
String comment = cursor.getString(cursor.getColumnIndex(Posts.COLUMN_COMMENT));
TextView dateView = (TextView) view.findViewById(R.id.textItemDate);
TextView userView = (TextView) view.findViewById(R.id.textItemUser);
TextView commentView = (TextView) view.findViewById(R.id.textItemComment);
ImageView imageView = (ImageView) view.findViewById(R.id.imageItemPhoto);
dateView.setText(date);
userView.setText(user);
commentView.setText(comment);
if(hasImage == 0) {
imageView.setVisibility(ImageView.GONE);
} else {
String bitmapPath = Environment.getExternalStorageDirectory().getPath() + "/feed/" + id + "_thumb.jpg";
Bitmap bitmap = BitmapFactory.decodeFile(bitmapPath);
BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
imageView.setImageDrawable(bitmapDrawable);
imageView.setVisibility(ImageView.VISIBLE);
}
}
}
스크롤은 이전에이 응용 프로그램을 작성한 방법과 매우 잘 작동했습니다. ArrayAdapter 및 ArrayList를 사용하여 ListView를 채 웁니다. 그러나 구현이 어떻게 작동하는지, 그리고이 SimpleCursorAdapter, Cursor 및 ListFragment가 어떻게 작동하는지에 대한 차이점이 있으며 무엇이 잘못되었거나 그 행동이 왜 이상한지를 정확히 지적 할 수 없습니다. 시도하고 자세히 설명해 주시겠습니까? ArrayList의 사용을 피하기 위해 커서를 사용합니다. ArrayList는 적어도 필요하지 않아야한다고 가정합니다. –
CursorAdapter가이 경우 어떻게 작동하는지 좀 더 명확하게 파악한 것 같아요. 분명히 요점이 있었을 것입니다. 당신이 설명했던 것을 이해하기 위해 새로운 것을 알았습니다. 아무도, 내 질문에 대한 대답으로 이것을 받아 들일 것입니다. –
내가 말하고자하는 것은 이제까지 U 위아래로 스크롤 할 때 어댑터와 다시 통신 할 것이며 커서가 목록의 항목과 비교할 때 올바른 위치에 있지 않을 때가되었습니다. 그래서 그것이 왜 표시되는지 생각합니다. 스크롤에 대한 다른 결과. 어쨌든 오늘은 사무실에서이 코드를 시험해보고 내가 가지고있는 것을 알려줍니다. –