我的问题是关于在Android中过滤。 Ebay和Foursquare都有一个看起来像是从右边滑入的对话框片段。在这个片段中有几个嵌套的列表视图,它们打开并展开以填充片段。打开嵌套列表视图时,顶部也会出现后退箭头。
选择过滤器后,它们会在顶级片段中的每个类别名称下显示为列表视图文本。 (请参阅"迪士尼"以及" HTC"在ebay屏幕截图中的不同颜色文字)
我想知道是否有一个库来实现这样的嵌套列表视图?这被认为是过滤搜索结果的最佳做法吗?
我已经提供了截图,希望能够展示我正在谈论的内容。
答案 0 :(得分:0)
答案 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();
}
}
构造过滤器的类似方法。添加您的想法。