为什么RecyclerView项目会随着滚动而消失

时间:2017-05-28 18:23:39

标签: android android-recyclerview

我在我的应用程序中使用RecyclerView但是当我滚动我的RecyclerView时,我的项目将消失!我将这段代码用于很多RecyclerView,但这次我不知道发生了什么。 有我的活动代码:

public class ActivityStartup extends AppCompatActivity {

  Toolbar toolbar;
  DrawerLayout drawerLayout;
  NavigationView navigationView;
  RecyclerView menuListRecycler;
  RecyclerView schedualRecycler;

  private List<ReminderModel> tempSchedualArray = new ArrayList<>();

  /**
   * ATTENTION: This was auto-generated to implement the App Indexing API.
   * See https://g.co/AppIndexing/AndroidStudio for more information.
   */
  private GoogleApiClient client;
  LinearLayoutManager mSchedualLayoutManager = new LinearLayoutManager(ActivityStartup.this);
  private FloatingActionButton mAddReminderButton;
  RecyclerView.Adapter mSchedualAdapter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    toolbar = (Toolbar) findViewById(R.id.toolBar);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    navigationView = (NavigationView) findViewById(R.id.navigationView);
    menuListRecycler = (RecyclerView) findViewById(R.id.menuList);
    schedualRecycler = (RecyclerView) findViewById(R.id.acitvityStartup_recycler_scheduals);

    //Setting Customized toolbar for application
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    LinearLayoutManager mEventsLayoutManager = new LinearLayoutManager(ActivityStartup.this);
    menuListRecycler.setLayoutManager(mEventsLayoutManager);
    RecyclerView.Adapter mEventsAdapter = new MenuAdapter(G.menuItems, ActivityStartup.this);
    menuListRecycler.setAdapter(mEventsAdapter);
    mAddReminderButton = (FloatingActionButton) findViewById(R.id.add_reminder);

    //Setting up recyclerView of events
    populateSchedualArray();

    schedualRecycler.setLayoutManager(mSchedualLayoutManager);
    mSchedualAdapter = new SchedualAdapter(populateSchedualArray(), ActivityStartup.this);
    schedualRecycler.setAdapter(mSchedualAdapter);

    // On clicking the floating action button
    mAddReminderButton.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        Intent intent = new Intent(v.getContext(), ReminderAddActivity.class);
        startActivity(intent);
      }
    });

  }

  @Override
  protected void onResume() {
    super.onResume();

    mSchedualAdapter = new SchedualAdapter(populateSchedualArray(), ActivityStartup.this);
    schedualRecycler.setAdapter(mSchedualAdapter);
  }



  private ArrayList<ReminderModel> populateSchedualArray() {

    ArrayList<ReminderModel> schedualArray = new ArrayList<>();

    Database rb = new Database(ActivityStartup.this);
    tempSchedualArray = rb.getAllReminders();

    ArrayList<ReminderModel> monthOne = new ArrayList<>();
    ArrayList<ReminderModel> monthTwo = new ArrayList<>();
    ArrayList<ReminderModel> monthThree = new ArrayList<>();
    ArrayList<ReminderModel> monthFour = new ArrayList<>();
    ArrayList<ReminderModel> monthFive = new ArrayList<>();
    ArrayList<ReminderModel> monthSix = new ArrayList<>();
    ArrayList<ReminderModel> monthSeven = new ArrayList<>();
    ArrayList<ReminderModel> monthEight = new ArrayList<>();
    ArrayList<ReminderModel> monthNine = new ArrayList<>();
    ArrayList<ReminderModel> monthTen = new ArrayList<>();
    ArrayList<ReminderModel> monthEleven = new ArrayList<>();
    ArrayList<ReminderModel> monthTwelve = new ArrayList<>();

    for (ReminderModel rm : tempSchedualArray) {

      String[] split = rm.getDate().split("/");
      switch (split[1]) {
        case "1":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthOne.add(rm);
          break;
        case "2":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthTwo.add(rm);
          break;
        case "3":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthThree.add(rm);
          break;
        case "4":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthFour.add(rm);
          break;
        case "5":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthFive.add(rm);
          break;
        case "6":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthSix.add(rm);
          break;
        case "7":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthSeven.add(rm);
          break;
        case "8":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthEight.add(rm);
          break;
        case "9":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthNine.add(rm);
          break;
        case "10":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthTen.add(rm);
          break;
        case "11":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthEleven.add(rm);
          break;
        case "12":
          rm.setDate(convertDateToGregorian(split[2], split[1], split[0]));
          monthTwelve.add(rm);
          break;
      }


    }

    schedualArray.add(new ReminderModel(100000001, "start_spring", "", "", "", "", "", ""));
    schedualArray.addAll(monthOne);
    schedualArray.addAll(monthTwo);
    schedualArray.addAll(monthThree);
    schedualArray.add(new ReminderModel(100000004, "start_summer", "", "", "", "", "", ""));
    schedualArray.addAll(monthFour);
    schedualArray.addAll(monthFive);
    schedualArray.addAll(monthSix);
    schedualArray.add(new ReminderModel(100000007, "start_fall", "", "", "", "", "", ""));
    schedualArray.addAll(monthSeven);
    schedualArray.addAll(monthEight);
    schedualArray.addAll(monthNine);
    schedualArray.add(new ReminderModel(1000000010, "start_winter", "", "", "", "", "", ""));
    schedualArray.addAll(monthTen);
    schedualArray.addAll(monthEleven);
    schedualArray.addAll(monthTwelve);

    return schedualArray;
  }

  private String convertDateToGregorian(String year, String month, String day) {

    CalendarTool calendarTool = new CalendarTool();
    calendarTool.setIranianDate(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));

    return calendarTool.getGregorianYear() + "/" + calendarTool.getGregorianMonth() + "/" + calendarTool.getGregorianDay();
  }


  @Override
  public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == android.R.id.home) {
      Toast.makeText(this, "دکمه خانه کلیک شد !", Toast.LENGTH_SHORT).show();
    }
    if (id == R.id.action_settings) {
      drawerLayout.openDrawer(Gravity.RIGHT);
      return true;
    }
    return super.onOptionsItemSelected(item);
  }

  /**
   * ATTENTION: This was auto-generated to implement the App Indexing API.
   * See https://g.co/AppIndexing/AndroidStudio for more information.
   */
  public Action getIndexApiAction() {
    Thing object = new Thing.Builder()
      .setName("Main Page") // TODO: Define a title for the content shown.
      // TODO: Make sure this auto-generated URL is correct.
      .setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
      .build();
    return new Action.Builder(Action.TYPE_VIEW)
      .setObject(object)
      .setActionStatus(Action.STATUS_TYPE_COMPLETED)
      .build();
  }

  @Override
  public void onStart() {
    super.onStart();
  }

  @Override
  public void onStop() {
    super.onStop();
  }


}

这是我使用的适配器类:

public class SchedualAdapter extends RecyclerView.Adapter<SchedualAdapter.ViewHolder> {
  private ArrayList<ReminderModel> items;
  private Context mContext;


  public SchedualAdapter(ArrayList<ReminderModel> items, Context mContext) {
    this.items = items;
    this.mContext = mContext;
  }

  public static class ViewHolder extends RecyclerView.ViewHolder {

    TextView txtDateNumber;
    TextView txtDateName;
    TextView txtEventTitle;
    TextView txtMonthName;
    ImageView imgMonth;
    LinearLayout layoutTop;

    public ViewHolder(View v) {
      super(v);

      txtDateNumber = (TextView) v.findViewById(R.id.txt_dateNumber);
      txtDateName = (TextView) v.findViewById(R.id.txt_dateName);
      txtEventTitle = (TextView) v.findViewById(R.id.txt_eventTitle);
      txtMonthName = (TextView) v.findViewById(R.id.txt_monthName);
      imgMonth = (ImageView) v.findViewById(R.id.img_monthPic);
      layoutTop = (LinearLayout) v.findViewById(R.id.layoutTop);
    }
  }

  @Override
  public SchedualAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    // Create a new View
    final View v = LayoutInflater.from(mContext).inflate(R.layout.schedual_recycler_item, parent, false);
    ViewHolder vh = new ViewHolder(v);
    return vh;
  }

  @Override
  public void onBindViewHolder(final ViewHolder holder, final int position) {

    if (items.get(position).getTitle().equals("start_spring")) {

      holder.imgMonth.setVisibility(View.VISIBLE);
      holder.imgMonth.setImageResource(R.drawable.spring);
      holder.txtDateName.setVisibility(View.GONE);
      holder.txtDateNumber.setVisibility(View.GONE);
      holder.txtEventTitle.setVisibility(View.GONE);
    } else if (items.get(position).getTitle().equals("start_summer")) {
      holder.imgMonth.setVisibility(View.VISIBLE);
      holder.imgMonth.setImageResource(R.drawable.summer);
      holder.txtDateName.setVisibility(View.GONE);
      holder.txtDateNumber.setVisibility(View.GONE);
      holder.txtEventTitle.setVisibility(View.GONE);
    } else if (items.get(position).getTitle().equals("start_fall")) {
      holder.imgMonth.setVisibility(View.VISIBLE);
      holder.imgMonth.setImageResource(R.drawable.fall);
      holder.txtDateName.setVisibility(View.GONE);
      holder.txtDateNumber.setVisibility(View.GONE);
      holder.txtEventTitle.setVisibility(View.GONE);
    } else if (items.get(position).getTitle().equals("start_winter")) {
      holder.imgMonth.setVisibility(View.VISIBLE);
      holder.imgMonth.setImageResource(R.drawable.winter);
      holder.txtDateName.setVisibility(View.GONE);
      holder.txtDateNumber.setVisibility(View.GONE);
      holder.txtEventTitle.setVisibility(View.GONE);
    } else {

      holder.imgMonth.setVisibility(View.GONE);

      holder.layoutTop.setVisibility(View.VISIBLE);
      holder.txtEventTitle.setText(items.get(position).getTitle());
      holder.txtDateNumber.setText(items.get(position).getDate());

      CalendarTool c = new CalendarTool();

      if (!items.get(position).getDate().equals("")) {

        String[] split = items.get(position).getDate().split("/");
        c.setIranianDate(Integer.parseInt(split[2]), Integer.parseInt(split[1]), Integer.parseInt(split[0]));
        holder.txtDateName.setText("" + c.getDayOfWeek());
      }

    }


    setAnimation(holder.itemView, position);

  }

  private int lastPosition = -1;

  private void setAnimation(View viewToAnimate, int position) {
    // If the bound view wasn't previously displayed on screen, it's animated
    if (position > lastPosition) {
      ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
      anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501)
      viewToAnimate.startAnimation(anim);
      lastPosition = position;
    }
  }

  @Override
  public int getItemCount() {
    return items.size();
  }
}

我无法理解我的物品会如何消失! 如果你能帮助我,我真的很感激。 谢谢。

5 个答案:

答案 0 :(得分:4)

我遇到了同样的问题(https://github.com/square/picasso/issues/845),但是在github中发现了这个问题,并为我工作。 Thaks到@ raj9686

rv.getRecycledViewPool().setMaxRecycledViews(0, 0);

答案 1 :(得分:2)

在recyclerView中使用muntiple视图时,为它们设置VISIBLE或GONE是不合适的,最好的方法是使用多个viewHolder进行recycleler查看:

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

import free.calendar.app.codenevisha.com.hamrahcalendar.R;
import model.ReminderModel;
import utils.G;

import static utils.G.SEASON_WINTER;


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

  private ArrayList<ReminderModel> items;
  private Context mContext;


  public SchedualAdapter(ArrayList<ReminderModel> items, Context mContext) {
    this.items = items;
    this.mContext = mContext;
  }

  public static class ViewHolderDefault extends RecyclerView.ViewHolder {

    TextView txt_eventTitle;
    TextView txt_dateNumber;
    TextView txt_dateName;

    public ViewHolderDefault(View v) {
      super(v);

      txt_eventTitle = (TextView) v.findViewById(R.id.txt_eventTitle);
      txt_dateName = (TextView) v.findViewById(R.id.txt_dateName);
      txt_dateNumber = (TextView) v.findViewById(R.id.txt_dateNumber);

    }
  }

  public static class ViewHolderSeason extends RecyclerView.ViewHolder {

    ImageView img_monthPic;

    public ViewHolderSeason(View v) {
      super(v);
      img_monthPic = (ImageView) v.findViewById(R.id.img_monthPic);
    }
  }

  @Override
  public int getItemViewType(int position) {

    /*
    * 0 default
    * 1 spring
    * 2 Summer
    * 3 fall
    * 4 winter
    */

    int state;
    String title = G.COMMON_DAY;
    if (items.get(position).getTitle().equals(G.SEASON_SPRING)) {
      return 1;
    } else if (items.get(position).getTitle().equals(G.SEASON_SUMMER)) {
      return 2;
    } else if (items.get(position).getTitle().equals(G.SEASON_FALL)) {
      return 3;
    } else if (items.get(position).getTitle().equals(SEASON_WINTER)) {
      return 4;
    }
    return 0;
  }

  @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    // Create a new View
    final View v1 = LayoutInflater.from(mContext).inflate(R.layout.schedual_recycler_default_viewgroup, parent, false);

    final View v2 = LayoutInflater.from(mContext).inflate(R.layout.schedual_recycler_seasion_viewgroup, parent, false);


    if (viewType == 0) {
      return new ViewHolderDefault(v1);
    } else {
      return new ViewHolderSeason(v2);
    }
  }

  @Override
  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {


    switch (holder.getItemViewType()) {
      case 0:
        ViewHolderDefault viewHolderDefault = (ViewHolderDefault) holder;
        viewHolderDefault.txt_dateNumber.setText(items.get(position).getDate());
        viewHolderDefault.txt_dateNumber.setText(items.get(position).getDate());
        break;

      case 1:
        ViewHolderSeason viewHolderSeason1 = (ViewHolderSeason) holder;
        viewHolderSeason1.img_monthPic.setImageResource(R.drawable.spring);
        break;

      case 2:
        ViewHolderSeason viewHolderSeason2 = (ViewHolderSeason) holder;
        viewHolderSeason2.img_monthPic.setImageResource(R.drawable.summer);
        break;

      case 3:
        ViewHolderSeason viewHolderSeason3 = (ViewHolderSeason) holder;
        viewHolderSeason3.img_monthPic.setImageResource(R.drawable.fall);
        break;

      case 4:
        ViewHolderSeason viewHolderSeason4 = (ViewHolderSeason) holder;
        viewHolderSeason4.img_monthPic.setImageResource(R.drawable.winter);
        break;
    }
  }


  @Override
  public int getItemCount() {
    return items.size();
  }
}

答案 2 :(得分:1)

与名称暗示的一样,Recycler视图重用现有项目中的视图类型,这些视图类型已经在相同类型中绘制,以避免绘制新的资源密集型项目。

这就是说这一行是你的罪魁祸首ggplot(fcast_data1, aes(x=weekday, y=mape_ExpExpFcstShort, labels("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"))) + geom_boxplot(outlier.shape=NA) + #avoid plotting outliers twice geom_jitter(position=position_jitter(width=.1, height=0)) + mytheme + ggtitle("May Forecast in May") 而不是holder.layoutTop.setVisibility(View.VISIBLE);使用if-else探索onBindViewHolder的使用。这是在回收站视图项中实现不同布局的正确方法。此stackoverflow问题应该提供一些见解How to create RecyclerView with multiple view type?

答案 3 :(得分:0)

您应该尝试使用getAdapterPosition / getLayoutPosition,而不是使用简单位置(实际上是adapterPosition AFAIK)。了解它们之间的差异。这可能有所帮助。如果不是你尝试使用不同的ViewTypes项目。祝你好运

答案 4 :(得分:0)

要隐藏包含多个项目的某些视图,最好隐藏基本布局,

1. Give an id to the base layout of the view in XML. 
2. Define the view inside your "RecyclerViewAdapter class"
LinearLayout mItems_timelineId;
mItems_timelineId = itemView.findViewById(R.id.items_timelineId);
3. Then remove the view wherever you wish to by,
mItems_timelineId.removeAllViews();

这对我有用。谢谢。