【问题标题】:ExpandableListView using SimpleCursorTreeAdapter scrolls to top on update使用 SimpleCursorTreeAdapter 的 ExpandableListView 在更新时滚动到顶部
【发布时间】:2014-04-11 03:19:43
【问题描述】:

我通过扩展 SimpleCursorTreeAdapter 创建了 ExpandableListAdapter。游标由加载器管理。当列表显示给用户时,我启动一个后台服务来从服务器获取最新数据。如果服务器返回新数据,我将其添加到 DB 并通知子游标。游标被请求并且列表更新。此时如果用户在列表中向下滚动,则列表向上滚动到顶部。这很烦人。我已经浏览了 *TreeAdapters 的整个 API,但没有看到任何阻止它的方法。这一定是一个非常普遍的问题。我该如何解决?

【问题讨论】:

    标签: android expandablelistview simplecursortreeadapter


    【解决方案1】:

    试试这个代码:

    public class GroupsAdapter extends SimpleCursorTreeAdapter {
    
        private final String TAG = getClass().getSimpleName().toString();
    
        private final FragmentActivity mActivity;
        private final ContactsFragment mFragment;
    
        private static final String[] CONTACTS_PROJECTION = new String[] {
                        ContactsContract.Users._ID, ContactsContract.Users.USER_ID,
                        ContactsContract.Users.NAME, ContactsContract.Users.STATUS_TYPE,
                        ContactsContract.Users.STATUS_MESSAGE,
                        ContactsContract.Users.HAS_ALERT };
    
        // Note that the constructor does not take a Cursor. This is done to avoid
        // querying the database on the main thread.
        public GroupsAdapter(final Context context, final ContactsFragment glf,
                        final int groupLayout, final int childLayout,
                        final String[] groupFrom, final int[] groupTo,
                        final String[] childrenFrom, final int[] childrenTo) {
    
                super(context, null, groupLayout, groupFrom, groupTo, childLayout,
                                childrenFrom, childrenTo);
                mActivity = (FragmentActivity) context;
                mFragment = glf;
        }
    
        @Override
        protected Cursor getChildrenCursor(final Cursor groupCursor) {
                final String id = groupCursor.getString(groupCursor
                                .getColumnIndex(ContactsContract.Groups.GROUP_ID));
                final CursorLoader cursorLoader = new CursorLoader(mActivity,
                                ContactsContract.Users.CONTENT_URI, CONTACTS_PROJECTION, "("
                                                + ContactsContract.UserGroupColumns.GROUP_ID + "=?)",
                                new String[] { id }, null);
    
                Cursor childCursor = null;
    
                try {
                        childCursor = cursorLoader.loadInBackground();
                        childCursor.moveToFirst();
                } catch (final Exception e) {
                        Log.e(TAG, e.getMessage());
                }
    
                return childCursor;
    
        }
    
    }
    

    和片段:

    public class ContactsFragment extends Fragment implements
                LoaderCallbacks<Cursor> {
    
        private static final String[] GROUPS_PROJECTION = new String[] {
                        ContactsContract.Groups._ID, ContactsContract.Groups.NAME,
                        ContactsContract.Groups.GROUP_ID,
                        ContactsContract.Groups.USERS_COUNT };
        private static final String TAG = "ContactsFragment";
    
        ExpandableListView listView;
        GroupsAdapter mAdapter;
    
        public ContactsFragment() {
                // Required empty public constructor
        }
    
        @Override
        public void onCreate(final Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setHasOptionsMenu(true);
        }
    
        @Override
        public View onCreateView(final LayoutInflater inflater,
                        final ViewGroup container, final Bundle savedInstanceState) {
                // Inflate the layout for this fragment
                return inflater.inflate(R.layout.fragment_contacts, container, false);
        }
    
        @Override
        public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
                inflater.inflate(R.menu.contacts_menu, menu);
                super.onCreateOptionsMenu(menu, inflater);
        }
    
        @Override
        public void onActivityCreated(final Bundle savedInstanceState) {
    
                super.onActivityCreated(savedInstanceState);
    
                listView = (ExpandableListView) getView().findViewById(
                                android.R.id.list);
                // listView.setEmptyView();
                // Set up our adapter
                mAdapter = new GroupsAdapter(getActivity(), R.layout.group,
                                R.layout.user, new String[] { ContactsContract.Groups.NAME,
                                                ContactsContract.Groups.USERS_COUNT }, // Name
                                // for group layouts
                                new int[] { R.id.group, R.id.count }, new String[] {
                                                ContactsContract.Users.NAME,
                                                ContactsContract.Users.STATUS_MESSAGE }, // Name
                                // for child layouts
                                new int[] { R.id.user_name, R.id.status_message });
    
                listView.setAdapter(mAdapter);
    
                // Prepare the loader. Either re-connect with an existing one,
                // or start a new one.
                final Loader<Cursor> loader = getLoaderManager().getLoader(-1);
                if (loader != null && !loader.isReset()) {
                        getLoaderManager().restartLoader(-1, null, this);
                } else {
                        getLoaderManager().initLoader(-1, null, this);
                }
                getActivity().getContentResolver().registerContentObserver(
                                ContactsContract.Users.CONTENT_URI, false,
                                new ContentObserver(null) {
                                        @Override
                                        public void onChange(final boolean selfChange) {
                                                Log.w(TAG, "Change");
                                        }
                                });
        }
    
        @Override
        public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
                // This is called when a new Loader needs to be created.
                // group cursor
                final CursorLoader cl = new CursorLoader(getActivity(),
                                ContactsContract.Groups.CONTENT_URI, GROUPS_PROJECTION, null,
                                null, null);
    
                return cl;
        }
    
        @Override
        public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
    
                // Swap the new cursor in.
                final int id = loader.getId();
    
                if (id == -1) {
    
                        mAdapter.setGroupCursor(cursor);
    
                }
    
        }
    
        @Override
        public void onLoaderReset(final Loader<Cursor> loader) {
                // This is called when the last Cursor provided to onLoadFinished()
                // is about to be closed.
                final int id = loader.getId();
                if (id != -1) {
                        // child cursor
                        try {
                                mAdapter.setChildrenCursor(id, null);
                        } catch (final NullPointerException e) {
                                Log.w("TAG", "Adapter expired, try again on the next query: "
                                                + e.getMessage());
                        }
                } else {
                        mAdapter.setGroupCursor(null);
                }
        }
    
    }
    

    【讨论】:

    • 谢谢你,你是救命稻草,你的解决方案解决了我的问题,我花了这么多时间,直到,我遇到了你的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    相关资源
    最近更新 更多