【问题标题】:Implement Android Search Filters like FourSquare or Ebay实现诸如 FourSquare 或 Ebay 之类的 Android 搜索过滤器
【发布时间】:2014-12-06 22:17:52
【问题描述】:

我的问题是关于 Android 中的过滤。 Ebay 和 Foursquare 都有一个看起来像是从右侧滑入的对话框片段。在这个片段中有几个嵌套的列表视图,它们打开并展开以填充片段。打开嵌套列表视图时,顶部也会出现一个后退箭头。

一旦选择过滤器,它们就会显示为顶级片段中每个类别名称下的列表视图文本。 (参见 ebay 截图中“Disney”和“HTC”的不同颜色文字)

我想知道是否有一个库可以实现这样的嵌套列表视图?这是否被认为是过滤搜索结果的最佳实践?

我已经包含了屏幕截图,希望能显示我在说什么。

【问题讨论】:

    标签: android search android-listview android-filter


    【解决方案1】:

    您可以通过带有自定义单元格的 android Expandable ListView 执行此操作。

    这是一个关于Expandable ListView 的示例,带有自定义单元格。

    谢谢

    【讨论】:

      【解决方案2】:

      可以通过android Recyclerview 和一些逻辑来实现。我曾通过以下方式处理过类似的情况。

      FilterViewAdapter - Adapter of Recycler.
      FilterListPresenter - class used to separate business logic.
      

      八种不同类型的单元格用于动态生成过滤器列表。

         static final int FILTER_HEADER = 0;
          static final int FILTER_DROPDOWN_HEADER = 1;
          static final int FILTER_DROPDOWN_ITEM_RADIO = 2;
          static final int FILTER_DROPDOWN_ITEM_CHECKBOX = 3;
          static final int FILTER_DROPDOWN_ITEM_RADIO_LAST = 22;
          static final int FILTER_DROPDOWN_ITEM_CHECKBOX_LAST = 33;
          static final int FILTER_DUEDATE = 4;
          static final int FILTER_PROGRESS = 5;
      

      getItemViewType() 提供基于逻辑的单元格类型。例如,如果打开过滤器,则提供与通常过滤器标题不同类型的单元格。

      @Override
          public int getItemViewType(int position) {
              return filterListPresenter.getItemViewType(position);
          }
      

      找到我的适配器类

      public class FilterViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements FilterListPresenter.AdapterCallBacks {
      
      
          FilterListPresenter filterListPresenter;
          Context context;
          public FilterViewAdapter(Context context,   FilterListPresenter filterListPresenter) {
              this.filterListPresenter = filterListPresenter;
              this.context = context;
              filterListPresenter.setAdapterCallback(this);
          }
      
          @Override
          public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
              View view = LayoutInflater.from(parent.getContext())
                      .inflate(filterListPresenter.getLayoutForView(viewType), parent, false);
              return filterListPresenter.getViewHolder(view,viewType);
          }
      
          @Override
          public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
            filterListPresenter.onBindCallLogRowViewAtPosition(position,holder,context);
          }
      
          @Override
          public int getItemViewType(int position) {
              return filterListPresenter.getItemViewType(position);
          }
      
          @Override
          public int getItemCount() {
              return filterListPresenter.getRowsCount();
          }
      
      
          @Override
          public void notifyDataSetChanged1() {
              notifyDataSetChanged();
          }
      }
      

      找到我的 Presenter 类

      public class FilterListPresenter<T extends RecyclerView.ViewHolder> implements FilterListener {
      
          static final int FILTER_HEADER = 0;
          static final int FILTER_DROPDOWN_HEADER = 1;
          static final int FILTER_DROPDOWN_ITEM_RADIO = 2;
          static final int FILTER_DROPDOWN_ITEM_CHECKBOX = 3;
          static final int FILTER_DROPDOWN_ITEM_RADIO_LAST = 22;
          static final int FILTER_DROPDOWN_ITEM_CHECKBOX_LAST = 33;
          static final int FILTER_DUEDATE = 4;
          static final int FILTER_PROGRESS = 5;
          Context context;
          SessionData sessionData;
          int openPosition = -1;
          List<FIlterData> fIlterDatas ;
      
          int numberOfRows = 5;
          String[] filterNAmes = {"Checkin Template", "Employee", "Due Date", "Percentage of progress", "Status"}; //Main filters
          int[] filterICons = {R.drawable.outline_view_agenda_black_24,
                  R.drawable.outline_person_black_24 ,
                  R.drawable.outline_calendar_today_black_24,
                  R.drawable.outline_trending_up_black_24,
                  R.drawable.outline_check_circle_black_24};
          private String checkBoxValue;
      
          public FilterListPresenter(Context context, SessionData sessionData) {
              this.context = context;
              this.sessionData  = sessionData;
              initilizeData(sessionData);
          }
      
          private void initilizeData(SessionData sessionData) {
              fIlterDatas = new ArrayList<>();
           //add data
      
          }
      
      
          public void onBindCallLogRowViewAtPosition(int position, T rowView, Context context) {
              int itemViewType = getItemViewType(position);
              switch (itemViewType) {
                  case FILTER_HEADER:
                      FilterHeaderHolder filterHeaderHolder = (FilterHeaderHolder) rowView;
                      filterHeaderHolder.setListener(this);
                      filterHeaderHolder.setTitle(getFilterTitle(position));
                      filterHeaderHolder.setImageView(getIcon(position), context);
                      break;
                  case FILTER_DROPDOWN_HEADER:
                      //add logic for each type cell
                      break;
                  case FILTER_DROPDOWN_ITEM_CHECKBOX:
                   case FILTER_DROPDOWN_ITEM_CHECKBOX_LAST:
                      break;
                  case FILTER_DROPDOWN_ITEM_RADIO:
                  case FILTER_DROPDOWN_ITEM_RADIO_LAST:
                      break;
                  case FILTER_PROGRESS:
      
                      break;
      
                  case FILTER_DUEDATE:
      
                      break;
      
              }
      
          }
      
          private int getIcon(int position) {
              if((openPosition == -1)  || (position<=openPosition))
                  return filterICons[position];
              else
                  return filterICons[position - getExtraRowCountForFIlter(openPosition)];
          }
      
          private String getFilterTitle(int position) {
              if((openPosition == -1)  || (position<=openPosition))
                  return filterNAmes[position];
              else
                  return filterNAmes[position - getExtraRowCountForFIlter(openPosition)];
          }
      
      
          public int getRowsCount() {
              if(openPosition == -1) return numberOfRows;
               else return numberOfRows+ getExtraRowCountForFIlter(openPosition);
          }
      
          private int getExtraRowCountForFIlter(int position) {
              switch (position){  //Additional one for header
                  case 0: return ((List<CheckinTemplate>) fIlterDatas.get(0).getFilterData()).size()+1;
                  case 1: try{return ((List<Employee>) fIlterDatas.get(1).getFilterData()).size()+1;}catch (Exception exc){
                               return 0;
                             }
                  case 4: return  ((List<Status>) fIlterDatas.get(4).getFilterData()).size()+1;
                  default: return 1;
              }
          }
      
          public int getItemViewType(int position) {  //Complex logic to determine my cell type
            if(openPosition == -1  || (position<=openPosition))
                return FILTER_HEADER;
            else {
                int extraRowsForOpenFilter = getExtraRowCountForFIlter(openPosition);
                if(position > (openPosition+extraRowsForOpenFilter))
                    return FILTER_HEADER;
      
                switch (openPosition){
                    case 0:
                        if(openPosition+1 == position)  return FILTER_DROPDOWN_HEADER;
                        else if(openPosition+extraRowsForOpenFilter == position)  return FILTER_DROPDOWN_ITEM_RADIO_LAST;
                        else return FILTER_DROPDOWN_ITEM_RADIO;
                    case 1:  if(openPosition+1 == position)  return FILTER_DROPDOWN_HEADER;
                             else if(openPosition+extraRowsForOpenFilter == position)  return FILTER_DROPDOWN_ITEM_CHECKBOX_LAST;
                             else return FILTER_DROPDOWN_ITEM_CHECKBOX;
                    case 4:
                        if(openPosition+1 == position)  return FILTER_DROPDOWN_HEADER;
                        else if(openPosition+extraRowsForOpenFilter == position)  return FILTER_DROPDOWN_ITEM_CHECKBOX_LAST;
                         else return FILTER_DROPDOWN_ITEM_CHECKBOX;
                    case 2:
                        return FILTER_DUEDATE;
                    case 3:
                        return FILTER_PROGRESS;
                    default: return FILTER_HEADER;
                }
            }
          }
      
          public int getLayoutForView(int viewType) {
              switch (viewType) {
                  case FILTER_HEADER:
                      return R.layout.a_filter_list_item_header;
                  case FILTER_DROPDOWN_HEADER:
                      return R.layout.a_filter_list_item_dropdown_header;
                  case FILTER_DROPDOWN_ITEM_RADIO:
                      return R.layout.a_filter_list_item_dropdown_item_radio;
                  case FILTER_DROPDOWN_ITEM_RADIO_LAST:
                      return R.layout.a_filter_list_item_dropdown_item_radio_last;
                  case FILTER_DROPDOWN_ITEM_CHECKBOX:
                      return R.layout.a_filter_list_item_dropdown_item_chekbox;
                  case FILTER_DROPDOWN_ITEM_CHECKBOX_LAST:
                      return R.layout.a_filter_list_item_dropdown_item_chekbox_last;
                  case FILTER_DUEDATE:
                      return R.layout.a_filter_list_item_duedate;
                  case FILTER_PROGRESS:
                      return R.layout.a_filter_list_item_progress;
              }
              return FILTER_HEADER;
          }
      
          @Override
          public void onFilterItemClick(int position, int viewTypeId) {
              switch (viewTypeId) {
                  case FILTER_HEADER:
                      if(openPosition!=-1) minimizeFilters();
                      else {
                          openPosition = position;
                          adapterCallback.notifyDataSetChanged1();
                      }
      
                  case FILTER_DROPDOWN_HEADER:
      
                      break;
                  case FILTER_DROPDOWN_ITEM_RADIO:
                  case FILTER_DROPDOWN_ITEM_RADIO_LAST:
      
      
                      break;
                  case FILTER_DROPDOWN_ITEM_CHECKBOX:
                  case FILTER_DROPDOWN_ITEM_CHECKBOX_LAST:
      
                      break;
                  case FILTER_DUEDATE:
      
                      break;
                  case FILTER_PROGRESS:
      
                      break;
      
              }
          }
      
          @Override
          public RecyclerView.ViewHolder getViewHolder(View view, int viewType) {
              switch (viewType) {
                  case FILTER_HEADER:
                      return new FilterHeaderHolder(view);
                  case FILTER_DROPDOWN_HEADER:
                      return new FilterListDropdownHeader(view);
                  case FILTER_DROPDOWN_ITEM_RADIO:
                  case FILTER_DROPDOWN_ITEM_RADIO_LAST:
                      return new FilterListItemRadioButton(view);
                  case FILTER_DROPDOWN_ITEM_CHECKBOX:
                  case FILTER_DROPDOWN_ITEM_CHECKBOX_LAST:
                      return new FilterListItemCheckBox(view);
                  case FILTER_DUEDATE:
                      return new FilterListItemDueDate(view);
                  case FILTER_PROGRESS:
                      return new FilterListItemProgress(view);
                  default:  return new FilterHeaderHolder(view);
              }
          }
      
          private void minimizeFilters() {
              openPosition = -1;
              adapterCallback.notifyDataSetChanged1();
          }
      
          AdapterCallBacks adapterCallback;
          public void setAdapterCallback(FilterViewAdapter adapterCallback) {
              this.adapterCallback = adapterCallback;
          }
      
          public String getDropdownHeader() {
              if( ((List<?>) fIlterDatas.get(openPosition).getFilterData()).get(0) instanceof CheckinTemplate){
                  return "Select Template";
              }else if( ((List<?>) fIlterDatas.get(openPosition).getFilterData()).get(0) instanceof Employee){
                  return "Select Employees";
              }else if( ((List<?>) fIlterDatas.get(openPosition).getFilterData()).get(0) instanceof Status){
                  return "Select status";
              }
              return "";
          }
      
          public String getCheckBoxValue(int pos) {
              if( ((List<?>) fIlterDatas.get(openPosition).getFilterData()).get(0) instanceof CheckinTemplate){
                  return ((List<CheckinTemplate>) fIlterDatas.get(openPosition).getFilterData()).get(pos).getName();
              }else if( ((List<?>) fIlterDatas.get(openPosition).getFilterData()).get(0) instanceof Employee){
                  return ((List<Employee>) fIlterDatas.get(openPosition).getFilterData()).get(pos).getEmpName();
              }else if( ((List<?>) fIlterDatas.get(openPosition).getFilterData()).get(0) instanceof Status){
                  return ((List<Status>) fIlterDatas.get(openPosition).getFilterData()).get(pos).getName();
              }
              return "";
          }
      
          public interface AdapterCallBacks{
              void notifyDataSetChanged1();
          }
      }
      

      构建过滤器的方法类似。添加您的想法。

      【讨论】:

        猜你喜欢
        • 2017-04-06
        • 2011-10-19
        • 1970-01-01
        • 2013-07-31
        • 1970-01-01
        • 1970-01-01
        • 2020-06-30
        • 2018-09-09
        • 1970-01-01
        相关资源
        最近更新 更多