RecyclerView - 如何更新适配器数据

时间:2015-03-11 13:07:42

标签: android recycler-adapter android-recyclerview

ScheduleAdapter中,我显示了一个能够展开/折叠行的列表。在ViewHolder中,imgToggle.setOnClickListener(...)处理click事件。这很好。

问题是当我滚动列表时,列表中较远的行(最初不可见)会自动展开。例如,如果我单击列表中的第一个项目,则该行会展开。当我滚动列表时,第六行(任意行:首先不可见)被展开(它不应该是)。

我了解RecyclerView正在做什么。只是不确定如何处理它?<​​/ p>

在我的代码中,我尝试使用scheduleDetailVisibility来管理扩展/ collaspe行为。这种方法不起作用。

我可以采取的另一种方法是向我的ScheduleTrip添加一个属性,该属性可以管理当前行是否已展开/折叠。我如何更新schedules以便适配器知道更改?

public class ScheduleAdapter extends RecyclerView.Adapter<ScheduleAdapter.ViewHolder> {

    private ArrayList<ScheduleTrip> schedules;
    private int rowLayout;
    private Context mContext;

    public ScheduleAdapter(ArrayList<ScheduleTrip> schedules, int rowLayout, Context context) {
        this.schedules = schedules;
        this.rowLayout = rowLayout;
        this.mContext = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowLayout, viewGroup, false);
        return new ViewHolder(v, mContext);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {

        ScheduleTrip schedule = schedules.get(i);
        viewHolder.textViewRoute.setText(schedule.trip_id);
        viewHolder.textViewTripHeadsign.setText(schedule.trip_name);
        viewHolder.tableTimes.removeAllViews();
        viewHolder.tableTimes.addView(buildTable(schedule.departure_time, i));
        viewHolder.scheduleDetail.setVisibility(viewHolder.scheduleDetailVisibility);
    }

    @Override
    public int getItemCount() {
        return schedules == null ? 0 : schedules.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public View view;

        public TextView textViewRoute;
        public TextView textViewTripHeadsign;
        public ImageView imgToggle;
        public int scheduleDetailVisibility = View.GONE;
        public LinearLayout scheduleDetail;
        public LinearLayout tableTimes;

        public ViewHolder(View itemView, final Context context) {
            super(itemView);

            scheduleDetailVisibility = View.GONE;
            textViewRoute = (TextView) itemView.findViewById(R.id.textViewRoute);
            textViewTripHeadsign = (TextView) itemView.findViewById(R.id.textViewTripHeadsign);
            tableTimes = (LinearLayout) itemView.findViewById(R.id.tableTimes);
            scheduleDetail = (LinearLayout) itemView.findViewById(R.id.scheduleDetail);
            imgToggle = (ImageView) itemView.findViewById(R.id.imgToggle);
            imgToggle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int visibility = scheduleDetail.getVisibility();
                    switch (visibility){
                        case View.GONE:
                        case View.INVISIBLE:
                            scheduleDetail.setVisibility(View.VISIBLE);
                            scheduleDetailVisibility = View.VISIBLE;
                            imgToggle.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_action_collapse));
                            break;
                        default:
                            scheduleDetail.setVisibility(View.GONE);
                            scheduleDetailVisibility = View.GONE;
                            imgToggle.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_action_expand));
                            break;
                    }
                }
            });
        }
    }   
}

2 个答案:

答案 0 :(得分:0)

试试这个

public ViewHolder(View itemView, final Context context) {
            super(itemView);

            scheduleDetailVisibility = View.GONE;
            textViewRoute = (TextView) itemView.findViewById(R.id.textViewRoute);
            textViewTripHeadsign = (TextView) itemView.findViewById(R.id.textViewTripHeadsign);
            tableTimes = (LinearLayout) itemView.findViewById(R.id.tableTimes);
            scheduleDetail = (LinearLayout) itemView.findViewById(R.id.scheduleDetail);
            imgToggle = (ImageView) itemView.findViewById(R.id.imgToggle);

            if (scheduleDetail.getTag()!=null){
                if(((Boolean) scheduleDetail .getTag())){
                    scheduleDetail.setVisibility(View.VISIBLE);
                }else{
                    scheduleDetail.setVisibility(View.GONE);
                }

            }else{
                scheduleDetail.setVisibility(View.VISIBLE);
            }

            imgToggle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int visibility = scheduleDetail.getVisibility();
                    switch (visibility){
                        case View.INVISIBLE:

            case View.GONE:
                            scheduleDetail.setVisibility(View.VISIBLE);
                            scheduleDetailVisibility = View.VISIBLE;
                            imgToggle.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_action_collapse));
scheduleDetail.setTag(true);
                            break;
                        default:
                            scheduleDetail.setVisibility(View.GONE);
                            scheduleDetailVisibility = View.GONE;
                            imgToggle.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_action_expand));
scheduleDetail.setTag(false);
                            break;
                    }
                }
            });

答案 1 :(得分:0)

希望你已经解决了你的问题。顺便提一下,我可以告诉你,如果你在使用RecyclerView实现可扩展列表视图时对适配器级别进行更改而不是使用View.Visibility,那么我可以更容易和可控制。 我建议你点击sopme可扩展项目,只需在适当的位置添加新项目并使用 RecyclerView.OnItemInserted()api。类似于折叠列表Item.Just从适配器的主数据列表中删除项目并调用 recyclerView.OnItemRangeRemoved(int intpos,int itemcount)。 我已经为零售应用程序的类别活动实现了这一点,其中一些类别是可扩展的。 这样做的另一个优点是RV的这些api有自己的动画,或者您可以自定义项目的内外动画,从而提供更好的用户体验和更好的性能。