CursorLoader多类型数据使用

2020-09-05  本文已影响0人  美晨菌
1. 配置CursorLoader id
private static final int LOADER_ID = 4;
2. 创建CursorLoader
  private void loadChatbotContactsCursor() {
      getLoaderManager().restartLoader(LOADER_ID, null, this);
  }
3. 重写onCreateLoader多种loader用id判断
  @Override
  public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
    LogUtil.i("NewSearchFragment.onCreateLoader", "loading cursor: " + id);
    if (id == CONTACTS_LOADER_ID) {
      return new SearchContactsCursorLoader(getContext(), query, isRegularSearch());
    } else if (id == NEARBY_PLACES_LOADER_ID) {
      // Directories represent contact data sources on the device, but since nearby places aren't
      // stored on the device, they don't have a directory ID. We pass the list of all existing IDs
      // so that we can find one that doesn't collide.
      List<Long> directoryIds = new ArrayList<>();
      for (Directory directory : directories) {
        directoryIds.add(directory.getId());
      }
      return new NearbyPlacesCursorLoader(getContext(), query, directoryIds);
    } else if (id == DIRECTORIES_LOADER_ID) {
      return new DirectoriesCursorLoader(getContext());
    } else if (id == DIRECTORY_CONTACTS_LOADER_ID) {
      return new DirectoryContactsCursorLoader(getContext(), query, directories);
    } else if (id == LOADER_ID) {
      return new ContactsLoader(getContext(), query);
    } else {
      throw new IllegalStateException("Invalid loader id: " + id);
    }
  }
4. onLoadFinished填充数据到Adapter
  @Override
  public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    LogUtil.i("NewSearchFragment.onLoadFinished", "Loader finished: " + loader);
    if (cursor != null
        && !(loader instanceof DirectoriesCursorLoader)
        && !(cursor instanceof SearchCursor)) {
      throw Assert.createIllegalStateFailException("Cursors must implement SearchCursor");
    }

    if (loader instanceof SearchContactsCursorLoader) {
      adapter.setContactsCursor((SearchCursor) cursor);

    } else if (loader instanceof NearbyPlacesCursorLoader) {
      adapter.setNearbyPlacesCursor((SearchCursor) cursor);

    } else if (loader instanceof DirectoryContactsCursorLoader) {
      adapter.setDirectoryContactsCursor((SearchCursor) cursor);

    } else if (loader instanceof DirectoriesCursorLoader) {
      directories.clear();
      directories.addAll(DirectoriesCursorLoader.toDirectories(cursor));
      loadNearbyPlacesCursor();
      loadDirectoryContactsCursors();
    } else if (loader instanceof ContactsLoader) {
      adapter.setContactsCursor((SearchCursor) cursor);
    } else {
      throw new IllegalStateException("Invalid loader: " + loader);
    }
  }
5. onCreateViewHolder根据getItemType创建不同ViewHolder
  @Override
  public ViewHolder onCreateViewHolder(ViewGroup root, @RowType int rowType) {
    switch (rowType) {
      case RowType.CONTACT_ROW:
        return new SearchContactViewHolder(
            LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false),
            rowClickListener);
      case RowType.NEARBY_PLACES_ROW:
        return new NearbyPlaceViewHolder(
            LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false),
            rowClickListener);
      case RowType.CONTACT_HEADER:
      case RowType.DIRECTORY_HEADER:
      case RowType.NEARBY_PLACES_HEADER:
        return new HeaderViewHolder(
            LayoutInflater.from(context).inflate(R.layout.header_layout, root, false));
      case RowType.DIRECTORY_ROW:
        return new DirectoryContactViewHolder(
            LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false),
            rowClickListener);
      case RowType.SEARCH_ACTION:
        return new SearchActionViewHolder(
            LayoutInflater.from(context).inflate(R.layout.search_action_layout, root, false),
            rowClickListener);
      case RowType.LOCATION_REQUEST:
        return new LocationPermissionViewHolder(
            LayoutInflater.from(context).inflate(R.layout.location_permission_row, root, false),
            allowClickListener,
            dismissClickListener);
      case RowType.INVALID:
      default:
        throw Assert.createIllegalStateFailException("Invalid RowType: " + rowType);
    }
  }
6. 绑定数据
  @Override
  public void onBindViewHolder(ViewHolder holder, int position) {
    if (holder instanceof SearchContactViewHolder) {
      ((SearchContactViewHolder) holder).bind(searchCursorManager.getCursor(position), query);
    } else if (holder instanceof NearbyPlaceViewHolder) {
      ((NearbyPlaceViewHolder) holder).bind(searchCursorManager.getCursor(position), query);
    } else if (holder instanceof DirectoryContactViewHolder) {
      ((DirectoryContactViewHolder) holder).bind(searchCursorManager.getCursor(position), query);
    } else if (holder instanceof HeaderViewHolder) {
      String header =
          searchCursorManager.getCursor(position).getString(SearchCursor.HEADER_TEXT_POSITION);
      ((HeaderViewHolder) holder).setHeader(header);
    } else if (holder instanceof SearchActionViewHolder) {
      ((SearchActionViewHolder) holder)
          .setAction(
              searchCursorManager.getSearchAction(position),
              position,
              TextUtils.isEmpty(rawNumber) ? query : rawNumber);
    } else if (holder instanceof LocationPermissionViewHolder) {
      // No-op
    } else {
      throw Assert.createIllegalStateFailException("Invalid ViewHolder: " + holder);
    }
  }
7. 获取类型
  @Override
  public @RowType int getItemViewType(int position) {
    return searchCursorManager.getRowType(position);
  }
8. position在Cursor之间定位
  SearchCursor getCursor(int position) {
    if (showLocationPermissionRequest) {
      if (position == 0) {
        return LOCATION_PERMISSION_CURSOR;
      }
      position--;
    }

    if (contactsCursor != null) {
      int count = contactsCursor.getCount();

      if (position - count < 0) {
        contactsCursor.moveToPosition(position);
        return contactsCursor;
      }
      position -= count;
    }

    if (!showLocationPermissionRequest && nearbyPlacesCursor != null) {
      int count = nearbyPlacesCursor.getCount();

      if (position - count < 0) {
        nearbyPlacesCursor.moveToPosition(position);
        return nearbyPlacesCursor;
      }
      position -= count;
    }
8. 获取数据类型
  int getRowType(int position) {
    int cursorCount = getCount();
    if (position >= cursorCount) {
      throw Assert.createIllegalStateFailException(
          String.format("Invalid position: %d, cursor count: %d", position, cursorCount));
    } else if (position >= cursorCount - searchActions.size()) {
      return RowType.SEARCH_ACTION;
    }

    SearchCursor cursor = getCursor(position);
    if (cursor == contactsCursor) {
      return cursor.isHeader() ? RowType.CONTACT_HEADER : RowType.CONTACT_ROW;
    }

    if (cursor == LOCATION_PERMISSION_CURSOR) {
      return RowType.LOCATION_REQUEST;
    }

    if (cursor == nearbyPlacesCursor) {
      return cursor.isHeader() ? RowType.NEARBY_PLACES_HEADER : RowType.NEARBY_PLACES_ROW;
    }

    if (cursor == corpDirectoryCursor) {
      return cursor.isHeader() ? RowType.DIRECTORY_HEADER : RowType.DIRECTORY_ROW;
    }
    throw Assert.createIllegalStateFailException("No valid row type.");
  }
上一篇 下一篇

猜你喜欢

热点阅读