2017-06-14 73 views
-1

我在使用bignerdranch's ExpandableRecyclerView时遇到了困难。我即将把它在一个片段上工作(请参阅图片1和2)。但是,当我选择不同布局的不同片段时,数据似乎停留在ExpandableRecyclerView中(请参阅图片3和4)。ExpandableRecyclerAdapter保留片段之间的数据

(我没有足够的代表处发表个人链接,这样的照片是在imgur album - 抱歉!)

这里是我的ExpandableRecyclerAdapter

public class myExpandRecylerAdapter extends ExpandableRecyclerAdapter<TitleParentViewHolder, TitleChildViewHolder> { 

LayoutInflater mInflater; 
assignment_class myAssignment; 
myQueueTask myQueueTask; 
Dialog dialog; 
Calendar myCalendar; 
DatePickerDialog.OnDateSetListener date; 
boolean DoneFlag = false; 

public myExpandRecylerAdapter(Context context, List<ParentObject> parentItemList) { 
    super(context, parentItemList); 
    mInflater = LayoutInflater.from(context); 
} 



@Override 
public TitleParentViewHolder onCreateParentViewHolder(ViewGroup viewGroup) { 
    View view = mInflater.inflate(R.layout.list_parent, viewGroup, false); 
    return new TitleParentViewHolder(view); 
} 

@Override 
public TitleChildViewHolder onCreateChildViewHolder(ViewGroup viewGroup) { 
    View view = mInflater.inflate(R.layout.list_child, viewGroup, false); 
    return new TitleChildViewHolder(view); 
} 

@Override 
public void onBindParentViewHolder(TitleParentViewHolder titleParentViewHolder, int i, Object o) { 
    ParentViewClass title = (ParentViewClass) o; 
    titleParentViewHolder.tvParent.setText(title.getTitle()); 

} 

@Override 
public void onBindChildViewHolder(final TitleChildViewHolder titleChildViewHolder, int i, Object o) { 
    // o instanceof class can be used to determine the class type and template this adapter 


    if (o instanceof assignment_class) { 
     Log.d("instanceof","assignment_class"); 
     myAssignment = (assignment_class) o; 
     titleChildViewHolder.tvTitle.setText(myAssignment.ass_name); 
     titleChildViewHolder.tvTime.setText(myAssignment.TimeLeft()); 

     titleChildViewHolder.itemView.setOnClickListener(new View.OnClickListener() { 


      @Override 
      public void onClick(View v) { 
       final assignment_class ModifiedAssignment = myAssignment; 


       dialog = new Dialog(titleChildViewHolder.itemView.getContext()); 
       dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
       dialog.setContentView(R.layout.assignment_dialog); 
       dialog.show(); 
       Log.d("onClick", "Child: " + myAssignment.toString()); 


       // Set the textView at the top to the ass_name to indicate which assignment is being modified 
       TextView Name = (TextView) dialog.findViewById(R.id.tvName); 
       Name.setText(myAssignment.ass_name); 


       Spinner DropDown = (Spinner) dialog.findViewById(R.id.spDropDown); 

       // Create an ArrayAdapter using the string array and a default spinner 
       ArrayAdapter<CharSequence> staticAdapter = ArrayAdapter.createFromResource(titleChildViewHolder.itemView.getContext(), R.array.class_list, android.R.layout.simple_spinner_item); 
       // Specify the layout to use when the list of choices appears 
       staticAdapter 
         .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

       // Apply the adapter to the spinner 
       DropDown.setAdapter(staticAdapter); 

       DropDown.setOnItemSelectedListener(new OnItemSelectedListener() { 
        @Override 
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
         Log.v("item", (String) parent.getItemAtPosition(position)); 
         myAssignment.class_id = position; 
         Log.d("Set", myAssignment.class_id.toString()); 
        } 

        @Override 
        public void onNothingSelected(AdapterView<?> parent) { 

        } 
       }); 

       // Initialize for DatePicker 
       myCalendar = Calendar.getInstance(); 

       // Adapter 
       date = new DatePickerDialog.OnDateSetListener() { 

        @Override 
        public void onDateSet(DatePicker view, int year, int monthOfYear, 
              int dayOfMonth) { 
         // TODO Auto-generated method stub 
         myCalendar.set(Calendar.YEAR, year); 
         myCalendar.set(Calendar.MONTH, monthOfYear); 
         myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); 

         //Set textview 
         String myFormat = "MM/dd/yyyy"; //In which you need put here 
         SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US); 
         ((TextView) dialog.findViewById(R.id.tvDate)).setText(sdf.format(myCalendar.getTime())); 
        } 

       }; 


       final TextView etDate = (TextView) dialog.findViewById(R.id.tvDate); 


       // Default to today 
       String myFormat = "MM/dd/yyyy"; //In which you need put here 
       SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US); 
       ((TextView) dialog.findViewById(R.id.tvDate)).setText(sdf.format(myCalendar.getTime())); 


       // OnClick will open the dialogue for DatePicker 
       etDate.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         new DatePickerDialog(dialog.getContext(), date, myCalendar 
           .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH), 
           myCalendar.get(Calendar.DAY_OF_MONTH)).show(); 
        } 
       }); 


       final TextView etTime = (TextView) dialog.findViewById(R.id.etTime); 
       //Default time 
       etTime.setText("00:00"); 


       // OnClick will open the dialogue for TimePicker 
       etTime.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         TimePickerDialog mTimePicker; 

         mTimePicker = new TimePickerDialog(dialog.getContext(), new TimePickerDialog.OnTimeSetListener() { 
          @Override 
          public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) { 
           etTime.setText(selectedHour + ":" + selectedMinute); 
          } 
         }, Calendar.HOUR_OF_DAY, Calendar.MINUTE, false); 
         mTimePicker.setTitle("Select Time"); 
         mTimePicker.show(); 
        } 
       }); 


       final Button Done = (Button) dialog.findViewById(R.id.bDone); 

       Done.setText("NOT DONE"); 
       Done.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         if (!DoneFlag) { 
          Done.setText("DONE"); 
          DoneFlag = true; 
         } else { 
          Done.setText("NOT DONE"); 
          DoneFlag = true; 
         } 
        } 
       }); 

       Button Cancel = (Button) dialog.findViewById(R.id.bCancel); 
       Button Confirm = (Button) dialog.findViewById(R.id.bConfirm); 
       Confirm.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 

         ModifiedAssignment.ass_id = myAssignment.ass_id; 
         ModifiedAssignment.ass_name = ((TextView) dialog.findViewById(R.id.tvName)).getText(); 
         ModifiedAssignment.class_id = 0; //TODO: This 

         // We have to convert etDate to Date 
         SimpleDateFormat parser_date = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); 
         try { 
          ModifiedAssignment.due = parser_date.parse(etDate.toString() + " " + etTime + ":00"); 
         } catch (ParseException e) { 
          e.printStackTrace(); 
         } 

         ModifiedAssignment.date_assigned = myAssignment.date_assigned; 
         ModifiedAssignment.done = ((((Button) dialog.findViewById(R.id.bDone)).getText() == "DONE")); 
         ModifiedAssignment.weight = 99; //TODO: This aswell 

         myQueueItem item = null; 
         try { 
          item = new myQueueItem(new assignment_class(myAssignment, ModifiedAssignment)); 
         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
         item.setMode("EDIT"); 
         myQueue.getInstance().addQueueItem(item); 

        } 
       }); 

       Cancel.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         dialog.cancel(); 
        } 
       }); 
      } 
     }); 

    } 

    if (o instanceof myQueueTask) { 
     myQueueTask = (myQueueTask) o; 
     titleChildViewHolder.tvTitle.setText(myQueueTask.toString()); 
     titleChildViewHolder.tvTime.setText("time"); 

    } 
} 


} 

回答

0

对于任何人谁运行到这个问题的解决方案非常简单,但值得了解这个问题。在我ExpandableRecyclerAdapter你可以看到,我试图用

if (o instanceof assignment_class) 

然而使它成为一个模板,我没有考虑到我的TitleCreator类,负责创建每个“行”持有的ParentViewClass名单这是负责儿童(下拉项目)。

的解决方案如下:

static TitleCreator _titleCreator; 
private static List<?> ListOfObjects,OldList; 
List<ParentViewClass> ClassNameArrayList; 

public TitleCreator(Context context) { 
    ClassNameArrayList = new ArrayList<>(); 
    OldList = ListOfObjects; 
    if (DetermineType() == RecylerAdapter.typeOfObjectsList.ASSIGN_CLASS) { 
     for (int i = 0; i < ListOfObjects.size(); i++) { 
      ParentViewClass ParentView = new ParentViewClass(((assignment_class) ListOfObjects.get(i)).ass_name.toString()); 
      ClassNameArrayList.add(ParentView); 
     } 
    } 
    if (DetermineType() == RecylerAdapter.typeOfObjectsList.QUEUETASK) { 
     for (int i = 0; i < ListOfObjects.size(); i++) { 
      ParentViewClass ParentView = new ParentViewClass((ListOfObjects.get(i)).toString()); 
      ClassNameArrayList.add(ParentView); 
     } 
    } 
} 

public static TitleCreator get(Context context, List<?> classList) { 
    ListOfObjects = classList; 
    if (_titleCreator == null || OldList != classList) 
     _titleCreator = new TitleCreator(context); 

    return _titleCreator; 
} 

//This lets us template RecyclerAdapter so 
public RecylerAdapter.typeOfObjectsList DetermineType() { 
    //Since we don't know the type, we have to deduce it. This is done by comparing the 0th element to expected types 
    if (!ListOfObjects.isEmpty()) { 
     if (ListOfObjects.get(0) instanceof myQueueTask) 
      return RecylerAdapter.typeOfObjectsList.QUEUETASK; 
     if (ListOfObjects.get(0) instanceof assignment_class) 
      return RecylerAdapter.typeOfObjectsList.ASSIGN_CLASS; 
    } 
    if (!ListOfObjects.isEmpty()) { 
     Log.d("ClassType", ListOfObjects.get(0).getClass().toString() + " has not been defined in TitleCreator.java"); 
    } else { 
     Log.d("TitleCreator", "Encountered a unknown class type. You're probably not seeing anything so go to TitleCreator.java to define what you want to view "); 
    } 
    return RecylerAdapter.typeOfObjectsList.NAN; 
} 

public List<ParentViewClass> getAll() { 
    return ClassNameArrayList; 
} 


public enum typeOfObjectsList { 
    ASSIGN_CLASS, QUEUETASK, NAN 
} 

线

OldList = ListOfObjects; 

当新TitleCreator(上下文)被调用被调用。该方法在两种情况下被调用:由于短路评估,它将首先评估为_titleCreator = null,因为它尚未启动。如果(_titleCreator == null || OldList!= classList)

2)如果(_titleCreator == NULL || OldList!=班级列表)如果有一个已经存在的_titleCreator和OldList(其被设置时,将创建一个新的TitleCreator到班级列表,这将被评估)等于在参数中传递的列表。

虽然我不熟悉软件设计,但我认为问题在于我使用TitlerCreator作为Singleton Pattern,因此信息保存在片段之间。