@Override int getViewTypeCount() { // , return VIEW_TYPE_COUNT; } @Override int getItemViewType(int position) { // Cursor c = (Cursor)getItem(position); int columnIndex = c.getColumnIndex(VIEW_TYPE_COLUMN); return c.getInt(columnIndex); } @Override void bindView(View view, Context context, Cursor c) { // int columnIndex = c.getColumnIndex(VIEW_TYPE_COLUMN); int viewType = c.getInt(columnIndex); switch(viewType) { case VIEW_TYPE_VIDEO: bindVideoView(view); break; case VIEW_TYPE_SUBSCRIPTION: // } } @Override View newView(Context context, Cursor cursor, ViewGroup parent) { // int columnIndex = c.getColumnIndex(VIEW_TYPE_COLUMN); int viewType = c.getInt(columnIndex); switch(viewType) { case VIEW_TYPE_VIDEO: return newVideoView(cursor); case VIEW_TYPE_SUBSCRIPTION: // } }
CursorAdapter
class will do everything itself: it initializes individual view caches for different types of representations, it’s up to itself whether to create new or reuse old views ... in general everything’s great, you just need to get VIEW_TYPE_COLUMN
in the cursor.column | video | author | tag | comment |
---|---|---|---|---|
id | video_id | author_id | tag_id | primary key in the corresponding table |
view_type | VIDEO | SUBSCRIPTION | SUBSCRIPTION | type of card to display |
content_type | videos | authors | tags | content type - or table name, if it is more convenient |
title | video_title | Null | Null | video title |
name | Null | author_name | tag_name | author name or tag name |
picture | link | link | link | picture link |
updated | timestamp | timestamp | timestamp | object update time on server |
SELECT 0 as view_type, 'videos' as content_type, title, NULL as name, picture, updated FROM videos UNION ALL SELECT 1 as view_type, 'authors' as content_type, NULL as title, name, picture, updated FROM authors UNION ALL SELECT 1 as view_type, 'tags' as content_type, NULL as title, name, picture, updated FROM tags ORDER BY updated
Cursor c = getContext().getContentResolver().query(Uri.parse("content://MyProvider/feed/"));
MyProvider.query
method, MyProvider.query
necessary to determine that the request is being MyProvider.query
to the Uri tape, and switch to the “intelligent” query building mode. Cursor query(Uri contentUri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { if (isFeedUri(contentUri)) return buildFeedUri(); // // ... } Cursor buildFeedUri() { // "-" HashSet<String> unionColumnsSet = new HashSet<String>(); // Uri , (videos, authors tags) List<Uri>contentUriList = getSubqueryContentUriList(); // viewType String[] viewTypeColumns = new String[contentUriList.size()]; // contentType String[] contentTypeColumns = new String[contentUriList.size()]; for (int i=0; i<contentUriList.size(); i++) { Uri contentUri = contentUriList.get(i); // viewTypeColumns[i] = getViewTypeExpr(contentUri); // "0 as view_type" // content_type contentTypeColumns[i] = getContentTypeExpr(contentUri); // "'videos' as content_type" // List<String> projection = getProjection(contentUri); // unionColumnsSet.addAll(projection); } // , , : , // content-type , . String[] subqueries = new String[contentUriList.size()]; for (int i=0; i<contentUriList.size(); i++) { Uri contentUri = contentUriList.get(i); SQLiteQueryBuilder builder = new SQLiteQueryBuilder(); builder.setTables(getTable(contentUri)); // "1 as content_type" // , builder // "SELECT X as Y" String[] unionColumns = prependContentTypeExpr(contentTypeColumns[i], unionColumnSet); // "" "0 as view_type" // , Set<String> projection = prependViewTypeExpr(viewTypeColumns[i], getProjection(contentUri)); // , String selection = computeWhere(contentUri); subqueries[i] = builder.buildUnionSubQuery( "content_type", // typeDiscriminatorColumn - , // unionColumns, projection, 0, getTable(contentUri), // content_type // ( ) selection, null, // selectionArgs - buildUnionSubQuery // ( API level 1, API level 11 - ) null, // groupBy null // having ); } // , . SQLiteQueryBuilder builder = new SQLiteQueryBuilder() String orderBy = "updated DESC"; String query = builder.buildUnionQuery( subqueries, orderBy, null // limit - , . ); return getDBHelper().getReadableDatabase().rawQuery( query, null // selectionArgs - ); }
content://MyProvider/feed/
our ContentProvider will generate the UNION request we need and give the necessary data to the adapter. @Override public Loader<Cursor> onCreateLoader(int loaderId, Bundle params) { return new CursorLoader( getContext(), Uri.parse("content://MyContentProvider/feed/"), ... ); }
content://MyProvider/feed/
; when our service saves the results of a request to the server API, ContentProvider automatically notifies about data changes via another Uri, content://MyProvider/videos/
. getContext.getContentResolver().notifyChange(Uri.parse("content://MyProvider/feed/", null));
Source: https://habr.com/ru/post/221851/
All Articles