0

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

Ayush Chauhan
  • 441
  • 7
  • 25

1 Answers1

0

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

@Override
int getItemViewType (int position) {
    return mCursorAdapter.getItemViewType(position);
}
Doron Yakovlev Golani
  • 5,188
  • 9
  • 36
  • 60
  • but whats the need of getItemViewType() in WeatherAdapter? – Ayush Chauhan Jul 11 '16 at 14:30
  • As far as I understand, the item type determines wherther the RecyclerView can reuse the view or create a new one instead of it. If you don't specify it, all views might be of the same type. – Doron Yakovlev Golani Jul 11 '16 at 14:34
  • Ok but how should i use item type in onCreateViewHolder() – Ayush Chauhan Jul 11 '16 at 14:48
  • I don't think you have to since your CursorAdapter.newView() does the actual view creation. BTW, since you have a ViewHolder in WeatherAdapter, you should consider using it instead of the findViewById() you are doing in bindView. – Doron Yakovlev Golani Jul 11 '16 at 15:02
  • yeah i know and will optimized my code after it is running properly...right now it is displaying the the weather in wrong way...its is assigning layout for today weather to tomorrow and some random day – Ayush Chauhan Jul 11 '16 at 15:20
  • BTW, should probably have a look at this question to see how to implement a RecyclerViewAdapter with DB support: http://stackoverflow.com/questions/26517855/using-the-recyclerview-with-a-database – Doron Yakovlev Golani Jul 11 '16 at 15:36
  • I have implemented my adapter class with the help of this answer on stackoverflow – Ayush Chauhan Jul 11 '16 at 15:41