RecyclerView not correctly displaying Heterogenous Layouts

我是研究僧i 提交于 2020-01-16 19:35:49

问题


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


回答1:


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

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


来源:https://stackoverflow.com/questions/38309177/recyclerview-not-correctly-displaying-heterogenous-layouts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!