国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android之常見ListView刷新順序的問題

2020-02-21 17:32:32
字體:
來源:轉載
供稿:網友

在適配器中修改或添加數據源后,大多數程序員都已經非常熟悉listview的刷新機制了,那么Android之常見ListView刷新順序的問題有哪些呢?下面就讓武林技術頻道小編帶你一起進入下文了解一下吧!

背景一個典型的ListView,每個Item顯示一個TextView,代表一個Task,需要實現二個編輯方式:一個是用CheckBox來標識任務已經完成,另一個要實現的編輯是刪除任務。對于完成的CheckBox就直接放在布局中就可,但對于刪除不想使用ContextMenu來實現編輯,對于像iOS中那樣的列表,它的刪除都是通過對列表中每個項目的手勢來觸發。這個實現起來并不難,可以用一個ViewSwitcher,Checkbox和刪除按扭是放入其中,讓ViewSwitcher來控制顯示哪一個,正常情況下顯示Checkbox,隱藏刪除按扭,然后當點擊Item時就顯示刪除按扭,隱藏Checkbox,這樣也更符合操作習慣,可以一個一個條目的刪除。
實現起來的方式如下:

?

?

?

?


public class ListOrderActivity extends Activity {
??? private ListView mTaskList;
??? private EditText mAddTaskEditor;
??? private LayoutInflater mFactory;

??? @Override
??? public void onCreate(Bundle savedInstanceState) {
??????? super.onCreate(savedInstanceState);
??????? setContentView(R.layout.list_activity);

??????? mFactory = LayoutInflater.from(getApplication());
??????? mTaskList = (ListView) findViewById(R.id.task_list);
??????? final View headerView = mFactory.inflate(R.layout.header_view, null);
??????? mTaskList.addHeaderView(headerView);
??????? mAddTaskEditor = (EditText) headerView.findViewById(R.id.task_editor);
??????? mAddTaskEditor.setOnKeyListener(new OnKeyListener() {
??????????? @Override
??????????? public boolean onKey(View view, int keycode, KeyEvent event) {
??????? ?if (keycode == KeyEvent.KEYCODE_DPAD_CENTER || keycode == KeyEvent.KEYCODE_ENTER) {
??????? ???? // finish editing
??????? ???? final InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
??????? ???? inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
??????? ???? final String text = mAddTaskEditor.getText().toString();
??????? ???? if (!TextUtils.isEmpty(text)) {
??????? ??final ContentValues values = new ContentValues(1);
??????? ??values.put(TaskColumns.TASK, text);
??????? ??values.put(TaskColumns.TYPE, Task.TYPE_TODAY);
??????? ??getContentResolver().insert(Task.CONTENT_URI, values);
??????? ???? }
??????? ???? mAddTaskEditor.setText("");
??????? ?}
??????? ?return false;
??????????? }
??????? });
??????? final Cursor cursor = getContentResolver().query(Task.CONTENT_URI, Task.PROJECTION, TaskColumns.TYPE + " = " + Task.TYPE_TODAY, null, null);
??????? final TaskAdapter adapter = new TaskAdapter(getApplication(), cursor);
??????? mTaskList.setAdapter(adapter);
??? }

??? private class TaskAdapter extends CursorAdapter {
??????? private Cursor mCursor;

??????? public TaskAdapter(Context context, Cursor c) {
??????????? super(context, c);
??????????? mCursor = c;
??????? }

??????? @Override
??????? public void bindView(View view, Context context, Cursor cursor) {
??????????? if (view? == null) {
??????????????? view = mFactory.inflate(R.layout.today_task_item, null);
??????????? }
??????????? final ViewSwitcher switcher = (ViewSwitcher) view.findViewById(R.id.action_switcher);
//??????????? if (switcher.getDisplayedChild() == 1) {
//??????? ?switcher.clearAnimation();
//??????? ?switcher.showPrevious();
//??????? ?switcher.clearAnimation();
//??????????? }
??????????? final CheckBox toggle = (CheckBox) view.findViewById(R.id.action_toggle_done);
??????????? final short done = cursor.getShort(ProjectionIndex.DONE);
??????????? final int id = cursor.getInt(ProjectionIndex.ID);
??????????? toggle.setOnCheckedChangeListener(null);
??????????? toggle.setChecked(done != 0);
??????????? toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() {
??????? ?@Override
??????? ?public void onCheckedChanged(CompoundButton view, boolean checked) {
??????? ???? final Uri uri = ContentUris.withAppendedId(Task.CONTENT_URI, id);
??????? ???? final ContentValues values = new ContentValues(1);
??????? ???? values.put(TaskColumns.DONE, checked ? 1 : 0);
??????? ???? getContentResolver().update(uri, values, null, null);
??????? ?}
??????????? });
??????????? view.setOnClickListener(new OnClickListener() {
???????? @Override
???????? public void onClick(View v) {
???????????? switcher.showNext();
???????????? if (switcher.getDisplayedChild() == 0) {
???????? ?switcher.getInAnimation().setAnimationListener(null);
???????? ?return;
???????????? }
???????????? final ImageView delete = (ImageView) v.findViewById(R.id.action_delete_task);
???????????? delete.setOnClickListener(new OnClickListener() {
????????? @Override
????????? public void onClick(View v) {
????????????? switcher.getInAnimation().setAnimationListener(new AnimationListener() {
????????? ?@Override
????????? ?public void onAnimationEnd(Animation animation) {
????????? ???? switcher.getInAnimation().setAnimationListener(null);
????????? ???? final Uri uri = ContentUris.withAppendedId(Task.CONTENT_URI, id);
????????? ???? getContentResolver().delete(uri, null, null);
????????? ?}

????????? ?@Override
????????? ?public void onAnimationRepeat(Animation animation) {
????????? ?}

????????? ?@Override
????????? ?public void onAnimationStart(Animation animation) {
????????? ?}
????????????? });
????????????? switcher.showPrevious();
????????? }
????? });
???????? }
???? });
??????????? TextView task = (TextView) view.findViewById(R.id.task);
??????????? final String taskContent = cursor.getString(ProjectionIndex.TASK);
??????????? if (done != 0) {
??????? ?final Spannable style = new SpannableString(taskContent);
??????? ?style.setSpan(new StrikethroughSpan(), 0, taskContent.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
??????? ?style.setSpan(new StyleSpan(Typeface.ITALIC) , 0, taskContent.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
??????? ?task.setText(style);
??????? ?task.setTextAppearance(getApplication(), R.style.done_task_item_text);
??????????? } else {
??????? ?task.setText(taskContent);
??????? ?task.setTextAppearance(getApplication(), R.style.task_item_text);
??????????? }
??????? }
??????? @Override
??????? public View newView(Context context, Cursor cursor, ViewGroup parent) {
??????????? View view = mFactory.inflate(R.layout.today_task_item, null);
??????????? return view;
??????? }

??????? @Override
??????? public void onContentChanged() {
??????????? mCursor.requery();
??????? }
??? }
}

?

?

?


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
??? android:layout_width="fill_parent"
??? android:layout_height="fill_parent"
??? android:orientation="vertical"
??? android:background="#f0f0f0"
??? android:paddingBottom="5dip"
??? android:paddingLeft="12dip"
??? android:paddingRight="12dip"
??? android:paddingTop="5dip" >
??? <ListView
??????? android:id="@+id/task_list"
??????? android:layout_width="fill_parent"
??????? android:layout_height="fill_parent"
??????? android:divider="@color/divider"
??????? android:dividerHeight="0.6dip" />
</LinearLayout>

?

?

?


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
? xmlns:android="http://schemas.android.com/apk/res/android"
? android:orientation="horizontal"
? android:layout_width="fill_parent"
? android:layout_height="wrap_content"
? android:layout_gravity="center"
? android:gravity="center">
??? <ViewSwitcher android:id="@+id/action_switcher"
??????? android:layout_width="wrap_content"
??????? android:layout_height="wrap_content"
??????? android:layout_gravity="center"
??????? android:gravity="center"
??????? android:inAnimation="@anim/action_switcher_in"
??????? android:outAnimation="@anim/action_switcher_out">
???? <CheckBox android:id="@+id/action_toggle_done"
???????? android:layout_width="wrap_content"
???????? android:layout_height="wrap_content"
???????? android:gravity="center"
???????? android:layout_gravity="center" />
???? <ImageView android:id="@+id/action_delete_task"
???????? android:src="@drawable/ic_delete"
???????? android:layout_width="48dip"
???????? android:layout_height="48dip"
???????? android:contentDescription="@string/delete_description"
???????? android:gravity="center"
???????? android:layout_gravity="center"
???????? android:scaleType="center" />
??? </ViewSwitcher>
?<TextView android:id="@+id/task"
?????????? style="@style/task_item_text" />
</LinearLayout>




問題
但這有一個問題,就是如果其中某個條目是處于刪除狀態,這時再添加一個新任務,或者點擊另外條目的Checkbox時,條目的狀態會錯亂,本來處于正常狀態的條目會處于刪除狀態!
原因分析
最開始以為是數據問題,因為事件的處理都是匿名的類,可能會指向不正確的外部數據,通過打印調試發現所有數據都是對的。最后通過在bindView方法中加LOG信息發現了原因:每次ListView刷新bindView的順序并不相同,原來處在第3的子View,刷新后可能被放在第1位置。ViewSwitcher的顯示狀態是它自己維護的,也就是說沒有在View的外部保存其應該顯示的狀態,所以當數據發生變化(Checkbox會引發數據變化)刷新列表時,原來處于刪除狀態的子View(可能在第4位置)現在可能變成了第2位置,造成了第二個處于刪除狀態,而第四個處于正常狀態。
解決方案
這個問題沒有完美解決方法,只能做一個Workaround的方法:那就是每次刷新bindView時把刪除狀態清掉,都換成默認狀態,這樣至少不會出現狀態混亂的狀況。但是,還是會看到刪除會閃一下。
要想完全解決這個問題就是避免在有其他方式導致數據變化時使用這種設計,這種設計僅適用于:整個列表僅有刪除,沒有其他方式能導致列表會刷新時,這時每當刪除時,直接把子View從ListView中移除,就不會出現混亂了。

同時也說明為什么我們每次bindView時要重新給子View添數據,而不是僅當創建子View添數據。因為每次刷新bindView時順序并不一定是先前的順序,所以一定要重新添數據。而數據通常是與View分享開來,或是在數據庫中,或是其他形式,會以特定的順序存在,它不會因為View的刷新而改變,所以為了不使用戶感覺狀態錯亂,就必須要重新按照數據的順序來給View填充數據。

通過武林技術頻道小編介紹的Android之常見ListView刷新順序的問題,相信大家都有了一定的了解,如需了解更多的相關資訊,請繼續關注武林技術頻道吧!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 璧山县| 会泽县| 九寨沟县| 普定县| 英山县| 沁水县| 河南省| 巨鹿县| 昌邑市| 云浮市| 谷城县| 徐州市| 杨浦区| 威远县| 吴旗县| 海南省| 平陆县| 崇阳县| 宁陕县| 兰州市| 加查县| 新民市| 白水县| 繁昌县| 丰县| 南宫市| 巨鹿县| 女性| 平遥县| 青神县| 合阳县| 威远县| 舒兰市| 玉龙| 广水市| 禄丰县| 科技| 贡觉县| 贡觉县| 当阳市| 新乡市|