实施Android搜索过滤器,如FourSquare或Ebay

时间:2014-10-12 03:24:21

标签: android search android-listview android-filter

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

选择过滤器后,它们会在顶级片段中的每个类别名称下显示为列表视图文本。 (请参阅"迪士尼"以及" HTC"在ebay屏幕截图中的不同颜色文字)

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

我已经提供了截图,希望能够展示我正在谈论的内容。

Ebay Filter Fragment top level Ebay Filter nested listview Foursquare Filter nested listview Foursquare Filter Fragment top level

2 个答案:

答案 0 :(得分:0)

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

以下是有关自定义单元格的Expandable ListView的示例。

由于

答案 1 :(得分:0)

可以通过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();
    }
}

找到我的演讲者班

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();
    }
}

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