RecyclerView无法正确显示异构布局 [英] RecyclerView not correctly displaying Heterogenous Layouts

查看:61
本文介绍了RecyclerView无法正确显示异构布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个天气应用程序,其中我想在RecyclerView中使用两个Views,并将其CursorAdapter作为其成员.我想使用一个视图来显示今天的天气,而另一个视图来显示其他日子的天气.我的RecyclerView工作正常,我什至显示了两种布局,但显示不正确,即我要用于今天天气的布局被明天的天气和列表中的倒数第二天使用

以下是我的RecyclerView适配器的代码:-

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

    private static int VIEW_TYPE_TODAY = 0;
    private static int VIEW_TYPE_FUTURE_DAY = 1;
    private static final int VIEW_TYPE_COUNT = 2;
    public CursorAdapter mCursorAdapter;
    private Context mContext;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        TextView date,weather,min,max;
        ImageView icon;
        public ViewHolder(View itemView) {
            super(itemView);
            date =(TextView) itemView.findViewById(R.id.list_item_date_textview);
            weather = (TextView) itemView.findViewById(R.id.list_item_forecast_textview);
            min = (TextView) itemView.findViewById(R.id.list_item_low_textview);
            max = (TextView) itemView.findViewById(R.id.list_item_high_textview);
            icon = (ImageView) itemView.findViewById(R.id.list_item_icon);
        }
    }



    // Provide a suitable constructor (depends on the kind of dataset)
    public WeatherAdapter(Context context, Cursor c,int flags) {
        mContext = context;
        mCursorAdapter = new CursorAdapter(mContext,c,flags) {
            @Override
            public View newView(Context context, Cursor cursor, ViewGroup parent) {
                int viewType = getItemViewType(cursor.getPosition());
                int layoutId = -1;
                if(viewType==VIEW_TYPE_TODAY)
                    layoutId = R.layout.list_item_forecast_today;
                else if(viewType==VIEW_TYPE_FUTURE_DAY)
                    layoutId = R.layout.list_item_forecast;
                View view = LayoutInflater.from(context).inflate(layoutId, parent, false);
                return view;
            }

            @Override
            public void bindView(View itemView, Context context, final Cursor cursor) {
                // our view is pretty simple here --- just a text view
                // we'll keep the UI functional with a simple (and slow!) binding.

                TextView date,weather,min,max;
                ImageView icon;

                date =(TextView) itemView.findViewById(R.id.list_item_date_textview);
                weather = (TextView) itemView.findViewById(R.id.list_item_forecast_textview);
                min = (TextView) itemView.findViewById(R.id.list_item_low_textview);
                max = (TextView) itemView.findViewById(R.id.list_item_high_textview);
                icon = (ImageView) itemView.findViewById(R.id.list_item_icon);

                int weatherId = cursor.getInt(ForecastFragment.COL_WEATHER_ID);
                icon.setImageResource(R.drawable.ic_launcher);
                long dateId = cursor.getLong(ForecastFragment.COL_WEATHER_DATE);
                date.setText(Utility.getDayName(mContext,dateId));
                String weatherDesc = cursor.getString(ForecastFragment.COL_WEATHER_DESC);
                weather.setText(weatherDesc);
                boolean isMetric = Utility.isMetric(mContext);
                double high = cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP);
                max.setText(Utility.formatTemperature(high, isMetric) + "/");
                double low = cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP);
                min.setText(Utility.formatTemperature(low, isMetric));
            }

            @Override
            public int getViewTypeCount() {
                return VIEW_TYPE_COUNT;
            }

            @Override
            public int getItemViewType(int position) {
                Log.e("getItemViewType: ",""+position);
                if(position == VIEW_TYPE_TODAY)
                    return VIEW_TYPE_TODAY;
                else
                    return VIEW_TYPE_FUTURE_DAY;
            }
        };
    }

    // Create new views (invoked by the layout manager)
    @Override
    public WeatherAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
        return new ViewHolder(v);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        mCursorAdapter.getCursor().moveToPosition(position);
        mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
        Cursor cursor = mCursorAdapter.getCursor();
        cursor.moveToPosition(position);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Cursor cursor = mCursorAdapter.getCursor();
                cursor.moveToPosition(position);
                if (!cursor.isClosed()) {
                    String locationSetting = Utility.getPreferredLocation(mContext);
                    Intent intent = new Intent(mContext.getApplicationContext(), DetailActivity.class)
                            .setData(WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
                                    locationSetting, cursor.getLong(ForecastFragment.COL_WEATHER_DATE)
                            ));
                    mContext.startActivity(intent);
                }
            }
        });
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mCursorAdapter.getCount();
    }


}

我无法理解实施中的错误.感谢进阶

解决方案

在WeatherAdapter中还应该具有getItemViewType().您只能在CursorAdapter中使用它.

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

I am developing a weather app in which i wanted to use two Views inside RecyclerView which is having CursorAdapter as its member. I want to use one View to display todays weather and other view to display other days weathers. My RecyclerView is working perfectly and i even displaying the two layouts but not correctly i.e layout i want to use for today's weather is used by tomorrow weather and second last day in the list

Following is the code for my RecyclerView Adapter :-

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

    private static int VIEW_TYPE_TODAY = 0;
    private static int VIEW_TYPE_FUTURE_DAY = 1;
    private static final int VIEW_TYPE_COUNT = 2;
    public CursorAdapter mCursorAdapter;
    private Context mContext;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        TextView date,weather,min,max;
        ImageView icon;
        public ViewHolder(View itemView) {
            super(itemView);
            date =(TextView) itemView.findViewById(R.id.list_item_date_textview);
            weather = (TextView) itemView.findViewById(R.id.list_item_forecast_textview);
            min = (TextView) itemView.findViewById(R.id.list_item_low_textview);
            max = (TextView) itemView.findViewById(R.id.list_item_high_textview);
            icon = (ImageView) itemView.findViewById(R.id.list_item_icon);
        }
    }



    // Provide a suitable constructor (depends on the kind of dataset)
    public WeatherAdapter(Context context, Cursor c,int flags) {
        mContext = context;
        mCursorAdapter = new CursorAdapter(mContext,c,flags) {
            @Override
            public View newView(Context context, Cursor cursor, ViewGroup parent) {
                int viewType = getItemViewType(cursor.getPosition());
                int layoutId = -1;
                if(viewType==VIEW_TYPE_TODAY)
                    layoutId = R.layout.list_item_forecast_today;
                else if(viewType==VIEW_TYPE_FUTURE_DAY)
                    layoutId = R.layout.list_item_forecast;
                View view = LayoutInflater.from(context).inflate(layoutId, parent, false);
                return view;
            }

            @Override
            public void bindView(View itemView, Context context, final Cursor cursor) {
                // our view is pretty simple here --- just a text view
                // we'll keep the UI functional with a simple (and slow!) binding.

                TextView date,weather,min,max;
                ImageView icon;

                date =(TextView) itemView.findViewById(R.id.list_item_date_textview);
                weather = (TextView) itemView.findViewById(R.id.list_item_forecast_textview);
                min = (TextView) itemView.findViewById(R.id.list_item_low_textview);
                max = (TextView) itemView.findViewById(R.id.list_item_high_textview);
                icon = (ImageView) itemView.findViewById(R.id.list_item_icon);

                int weatherId = cursor.getInt(ForecastFragment.COL_WEATHER_ID);
                icon.setImageResource(R.drawable.ic_launcher);
                long dateId = cursor.getLong(ForecastFragment.COL_WEATHER_DATE);
                date.setText(Utility.getDayName(mContext,dateId));
                String weatherDesc = cursor.getString(ForecastFragment.COL_WEATHER_DESC);
                weather.setText(weatherDesc);
                boolean isMetric = Utility.isMetric(mContext);
                double high = cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP);
                max.setText(Utility.formatTemperature(high, isMetric) + "/");
                double low = cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP);
                min.setText(Utility.formatTemperature(low, isMetric));
            }

            @Override
            public int getViewTypeCount() {
                return VIEW_TYPE_COUNT;
            }

            @Override
            public int getItemViewType(int position) {
                Log.e("getItemViewType: ",""+position);
                if(position == VIEW_TYPE_TODAY)
                    return VIEW_TYPE_TODAY;
                else
                    return VIEW_TYPE_FUTURE_DAY;
            }
        };
    }

    // Create new views (invoked by the layout manager)
    @Override
    public WeatherAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
        return new ViewHolder(v);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        mCursorAdapter.getCursor().moveToPosition(position);
        mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
        Cursor cursor = mCursorAdapter.getCursor();
        cursor.moveToPosition(position);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Cursor cursor = mCursorAdapter.getCursor();
                cursor.moveToPosition(position);
                if (!cursor.isClosed()) {
                    String locationSetting = Utility.getPreferredLocation(mContext);
                    Intent intent = new Intent(mContext.getApplicationContext(), DetailActivity.class)
                            .setData(WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
                                    locationSetting, cursor.getLong(ForecastFragment.COL_WEATHER_DATE)
                            ));
                    mContext.startActivity(intent);
                }
            }
        });
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mCursorAdapter.getCount();
    }


}

I am not able to understand what wrong in my implementation.Thanks in advanced

解决方案

You should also have a getItemViewType() in WeatherAdapter. You only have it in the CursorAdapter.

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

这篇关于RecyclerView无法正确显示异构布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆