ExpandableListView не заполняется в новом фрагменте с использованием FirebaseDatabase - PullRequest
0 голосов
/ 24 июня 2018

КОД

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, чтобы создать фрагмент).Чтобы уточнить, это не будет заполнять КАЖДЫЙ раз, когда фрагмент был создан, обычно мне приходилось создавать фрагмент (пустой), нажимать кнопку «Назад», а затем повторно нажимать на ListViewItem, чтобы воссоздать его, и большую часть времени этоЗаполните его.

Я использовал эти успешные попытки, чтобы убедиться, что фактическая логика создания детей содержит правильные данные, но после того, как я получил эту работу, я решил попытаться решить все, что мешало заполнению моего ExpListНа 100%, поэтому я перестал использовать мой статический ArrayList mParentStepsList и вместо этого добавил в список мой класс QuestObject, но теперь он вообще не заполняется.Я получаю сообщение об ошибке notifyDataSetChanged, говоря: "

Blockquote

Убедитесь, что содержимое вашего адаптера не изменено из фонового потока, а только из потока пользовательского интерфейса.Убедитесь, что ваш адаптер вызывает notifyDataSetChanged () при изменении его содержимого. [В ListView (2131296258, класс android.widget.ExpandableListView) с адаптером (класс android.widget.ExpandableListConnector "

Blockquote

Ниже приведен список того, что я пробовал.

То, что я пробовал

Я немного прочитал и увидел, что нужно позвонитьnotifyDataSetChanged и поэтому я потратил 8 часов на то, чтобы поместить этот метод и вызвать его на моем адаптере всеми способами. Я пробовал выполнить runOnUIThread () 6 способов с воскресенья и каждую комбинацию, о которой я могу думать, и, честно говоря, я просто озадачен. Я надеюсь, что кто-то можетпомогите мне. Большое спасибо за ваше время

1 Ответ

0 голосов
/ 24 июня 2018

Я смог заставить его работать. Я вызываю notifyDataSetChanged как в onResume (), так и в onChildAdded () в childEventListener.

Я думаю, что причина, по которой я не пробовал этот конкретный способ ранее, заключается в том, что я предполагал, что вы вызовете notifyDataSetChange после того, как закончите добавлять группу данных, но, похоже, я должен был сделать это после КАЖДОГО изменения отдельных данных. onChildAdded вызывается каждый раз для каждого дочернего элемента DatabaseReference - поэтому я должен вызывать его каждый раз в этом методе

РЕДАКТИРОВАТЬ 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);


}
...