使用FirebaseDatabase在新片段中未填充ExpandableListView

时间:2018-06-24 08:21:50

标签: java android firebase firebase-realtime-database notifydatasetchanged

代码

public class QuestInspectingFragment extends Fragment{
// public static ArrayList<String> mParentStepsList;

public ArrayList<QuestObject> mRealQuests;
public ArrayList<QuestObject> mQuestObjectList;


ExpandableListView ExpListView;
LinearLayout toolBarLayout;
ChildEventListener mStepsListener;
DatabaseReference mStepsReference ;
String referencePath;
QuestExpListAdapter questAdapter;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.quest_inspect_fragment,container,false);
    referencePath = "versions/"+getArguments().getString("questPath")+"/Steps";
    mStepsReference = FirebaseHelper.mDatabase.getReference().child(referencePath);
    ExpListView = v.findViewById(R.id.ExpandableList);

    mQuestObjectList = new ArrayList<>();
    questAdapter = new QuestExpListAdapter(this.getContext(),mQuestObjectList);

    createStepsListener();

    ExpListView.setAdapter(questAdapter);

    return v;
}

@Override
public void onResume() {

    super.onResume();
    mStepsReference.addChildEventListener(mStepsListener);

}

@Override
public void onPause() {

    super.onPause();
    mStepsReference.removeEventListener(mStepsListener);


}

public static Fragment createInspectFragment(String pathToQuest){
    QuestInspectingFragment questInspectingFragment = new QuestInspectingFragment();
    Bundle myBundle = new Bundle();
    myBundle.putString("questPath",pathToQuest);

    questInspectingFragment.setArguments(myBundle);

    return questInspectingFragment;
}

public void createStepsListener(){

    mStepsListener = new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            //System.out.println((String)dataSnapshot.getKey()+"\n \n \n \n \n \n");
            QuestObject mQuest = new QuestObject();
            //Populate Step Items
            if(dataSnapshot.hasChild("title")){

                mQuest.setmStepTitleList((String)dataSnapshot.child("title").getValue());
            }else {
                mQuest.setmStepTitleList((dataSnapshot.getKey().toUpperCase()));
            }

            //Populate Substeps Items
            if (dataSnapshot.hasChild("Substeps")){

                for(DataSnapshot childSnapshot : dataSnapshot.child("Substeps").getChildren()){

                  System.out.println((String)childSnapshot.getKey()+"\n \n \n \n \n \n");
                  if(childSnapshot.hasChild("title")){
                    mQuest.mSubstepTitle.add ((String)childSnapshot.child("title").getValue());
                    ;
                }

                //populate subsubsteps
                  if(childSnapshot.hasChild("subsubstep")){
                    QuestObject.SubsubstepList mList = new QuestObject.SubsubstepList();
                    for(DataSnapshot subsubstep : childSnapshot.child("subsubstep").getChildren()){
                        mList.mclassSubstepList.add((String) subsubstep.child("title").getValue());

                    }
                    mQuest.mSubSubstep.add(mList);

                }
            }}

             mQuestObjectList.add(mQuest);



        }

        @Override
        public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    };


}

}

CustomExpandableListAdapter

public class QuestExpListAdapter extends BaseExpandableListAdapter {
private Context mContext;
 ArrayList<QuestObject> mQuestsList;

public QuestExpListAdapter(Context context,ArrayList<QuestObject> newQuestList){
    mContext = context;
   this.mQuestsList = newQuestList;


}

@Override
public int getGroupCount() {
    return mQuestsList.size();
}

@Override
public int getChildrenCount(int groupPosition) {
    return 1;
}

@Override
public Object getGroup(int groupPosition) {
    return groupPosition;
}

@Override
public Object getChild(int groupPosition, int childPosition) {
    return childPosition;
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return 0;
}

@Override
public boolean hasStableIds() {
    return true;
}


@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
   View row = convertView;
   MyViewHolder mvh = null;
    if(row == null){
       LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       row = inflater.inflate(R.layout.quest_exp_row1,null);
       mvh = new MyViewHolder(row);
       row.setTag(mvh);
   }else {
        mvh = (MyViewHolder) row.getTag();
    }
    mvh.step.setText("Step "+(groupPosition+1)+":"+mQuestsList.get(groupPosition).mStepTitleList);

    return row;
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

    SubstepExpandableList substepExpList = new SubstepExpandableList(mContext);
    substepExpList.setAdapter(new SubstepListAdapter(mContext, mQuestsList.get(groupPosition).mSubstepTitle, mQuestsList.get(groupPosition).mSubSubstep));
    substepExpList.setGroupIndicator(null);
    return substepExpList;

}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}


public class SubstepExpandableList extends ExpandableListView {
    public SubstepExpandableList(Context context) {
        super(context);
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //999999 is a size in pixels. ExpandableListView requires a maximum height in order to do measurement calculations.
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(999999, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
public class SubstepListAdapter extends BaseExpandableListAdapter{
    ArrayList<String> myPassedList;
    ArrayList<QuestObject.SubsubstepList> mySecondList;
    private Context mmContext;
    public SubstepListAdapter(Context context, ArrayList<String> myPassedList,ArrayList<QuestObject.SubsubstepList> myList ){
        mmContext = context;
        this.myPassedList = myPassedList;
        this.mySecondList = myList;
    }

    @Override
    public int getGroupCount() {
        return myPassedList.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {

       try {
           return mySecondList.get(groupPosition).mclassSubstepList.size();
        }catch (IndexOutOfBoundsException e){
           Toast.makeText(mmContext,"No Further Steps",Toast.LENGTH_SHORT).show();
           return 0;
       }
        //else {
       //     Toast.makeText(mmContext,"No Further Steps",Toast.LENGTH_SHORT).show();
       //     return 1;
       // }

    }

    @Override
    public Object getGroup(int groupPosition) {
        return groupPosition;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public long getGroupId(int groupPosition) {
        return 0;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        View row = convertView;
        MyViewHolder mvh = null;

        if(row == null){
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.quest_exp_row2,null);
            mvh = new MyViewHolder(row);
            row.setTag(mvh);
        }else {
            mvh = (MyViewHolder) row.getTag();

        }

        mvh.substep.setText(myPassedList.get(groupPosition));

        return row;


    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        View row = convertView;
        MyViewHolder mvh = null;

        if(row == null){
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.quest_exp_row3,null);
            mvh = new MyViewHolder(row);
            row.setTag(mvh);
        }else {
            mvh = (MyViewHolder) row.getTag();

        }
        if(mySecondList.get(groupPosition)!= null ) {
            if (mySecondList.get(groupPosition).mclassSubstepList.size() !=0){
            mvh.subsub.setText(mySecondList.get(groupPosition).mclassSubstepList.get(childPosition));
        }}
        return row;


    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }
}

private class MyViewHolder{

    TextView step;
    TextView substep;
    TextView subsub;
    MyViewHolder(View v){

        step = v.findViewById(R.id.questRow1Text);
        substep = v.findViewById(R.id.questRow2Text);
        subsub =v.findViewById(R.id.questRow3Text);



    }


}

}

public class QuestObject {
public void setmStepTitleList(String mStepTitleList) {
    this.mStepTitleList = mStepTitleList;
}

public String mStepTitleList ;
public ArrayList<String> mSubstepTitle = new ArrayList<>();
public ArrayList<SubsubstepList> mSubSubstep = new ArrayList<>();




public static class SubsubstepList{

    ArrayList<String> mclassSubstepList = new ArrayList<>();


}

}

问题描述 我有我的自定义适配器,它具有第二个ExpandableList作为每个父级的子级。我知道它的工作原理是我成功填充了它,但是单击(从listView创建片段)时经常 ONLY 。为了澄清起见,它不会在每次创建片段时都填充,通常我必须创建fragment(empty),单击“后退”按钮,然后重新单击ListViewItem来重新创建它,并且在大多数情况下,填充它。

我使用了那些成功的尝试来确保使子代包含正确数据的实际逻辑,但是在我能够正常工作之后,我决定尝试解决阻止ExpList始终填充100%的问题,因此我停止使用我的静态ArrayList mParentStepsList,而是将列表添加到QuestObject类中,但是现在根本没有填充。 我收到有关notifyDataSetChanged的错误,说“

  

Blockquote

确保没有从后台线程修改适配器的内容,而仅从UI线程修改了适配器的内容。确保适配器在其内容更改时调用notifyDataSetChanged()。 [在ListView(2131296258,类android.widget.ExpandableListView)中带有适配器(类android.widget.ExpandableListConnector“

  

Blockquote

下面是我尝试过的事情的清单。

我尝试过的事情

我进行了一些阅读,看到了有关需要调用notifyDataSetChanged的内容,因此我花了8个小时来放置该方法,并以各种方式在我的适配器上对其进行调用。从周日开始,我已经尝试了6种方法runOnUIThread()以及我能想到的每种组合,说实话,我刚刚遇到了麻烦。我希望有一个人可以帮助我。非常感谢您的时间

1 个答案:

答案 0 :(得分:0)

我能够使其正常运行。我在childEventListener的onResume()和onChildAdded()中都调用了notifyDataSetChanged。

我在想我没有较早尝试这种特定方式的原因是因为我假设添加完一堆数据后调用了notifyDataSetChange,但是看来我应该在每次更改单个数据后都这样做。每次为DatabaseReference的每个子对象调用onChildAdded,因此我应该在该方法中每次调用它

编辑1 -我不需要在onResume中调用它,而且我也将适配器设为静态。希望这对某人有帮助

mStepsListener = new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            //System.out.println((String)dataSnapshot.getKey()+"\n \n \n \n \n \n");
            QuestObject mQuest = new QuestObject();
            //Populate Step Items
            if(dataSnapshot.hasChild("title")){

                mQuest.setmStepTitleList((String)dataSnapshot.child("title").getValue());
            }else {
                mQuest.setmStepTitleList((dataSnapshot.getKey().toUpperCase()));
            }

            //Populate Substeps Items
            if (dataSnapshot.hasChild("Substeps")){

                for(DataSnapshot childSnapshot : dataSnapshot.child("Substeps").getChildren()){

                  System.out.println((String)childSnapshot.getKey()+"\n \n \n \n \n \n");
                  if(childSnapshot.hasChild("title")){
                    mQuest.mSubstepTitle.add ((String)childSnapshot.child("title").getValue());
                    //mSubstepList.add((String)childSnapshot.child("title").getValue());
                }

                //populate subsubsteps
                  if(childSnapshot.hasChild("subsubstep")){
                    QuestObject.SubsubstepList mList = new QuestObject.SubsubstepList();
                    for(DataSnapshot subsubstep : childSnapshot.child("subsubstep").getChildren()){
                        mList.mclassSubstepList.add((String) subsubstep.child("title").getValue());
                       // mSubSubStepList.add((String) subsubstep.child("title").getValue());
                    }
                    mQuest.mSubSubstep.add(mList);

                }
            }}

             mQuestObjectList.add(mQuest);

            **questAdapter.notifyDataSetChanged();**

        }

 public void onResume() {
    //mQuestObjectList = new ArrayList<>();

    super.onResume();

    mStepsReference.addChildEventListener(mStepsListener);
    getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {

            questAdapter.notifyDataSetChanged();
        }
    });


}

@Override
public void onPause() {
    questAdapter.mQuestsList.clear();
    super.onPause();
    mStepsReference.removeEventListener(mStepsListener);


}