2016-12-29 8 views
0

Ich verwende die Firebase-Benutzeroberfläche und erhalte ein eindeutiges Problem. Wenn ich den RecyclerView lade, gibt es keine Probleme. Ich klicke auf ein Element in der RecyclerView und erhalte den .push() Wert des Elements, auf das geklickt wurde. Anschließend werden Daten aus diesem Firebase .push() - Wert, der in der Firebase-Datenbank gespeichert ist, und an eine andere Aktivität gesendet. Siehe Bilder unter:Firebase RecylcerView-Adapter wird nicht korrekt angezeigt

enter image description here enter image description here

Das zweite Bild ist die Aktivität, die Daten über eine Absicht empfängt. Wenn ich zurück auf den RecyclerView klicke, klicke ich wieder auf "8" und lade eine andere Nummer (momentan scheint es 1 zu sein).

Letztendlich mache ich mir Sorgen, dass ich den RecyclerView nicht korrekt eingerichtet habe. Hier ist mein Code:

erstellen Poll-Objekt (POJO) und Firebase schreiben:

 mSubmitPollCreation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      //TODO: Need to check if poll requirements are added, i.e. Question, Answer, ...... 
      //check if image has been loaded first 
      if (resultImageURL == null) { 
       Toast.makeText(getApplicationContext(), getResources().getString(R.string.no_image_selected), Toast.LENGTH_LONG).show(); 
       return; 
      } 

      //capture answers 
      if (mNumberOfPollAnswersCreatedByUser > 5) { 
       Toast.makeText(getApplicationContext(), getResources().getText(R.string.poll_answers_greater_than_five), Toast.LENGTH_LONG).show(); 
       mNumberOfPollAnswersCreatedByUser = 5; 
      } 
      for (int i = 0; i < mNumberOfPollAnswersCreatedByUser; i++) { 
       EditText editText = (EditText) mEditTextAnswerLayout.findViewWithTag(getResources().getString(R.string.created_answer_editText_id) + String.valueOf(i + 1)); 
       String editTextInputForAnswer = String.valueOf(editText.getText()); 
       mPollAnswers.add(0, editTextInputForAnswer);     Toast.makeText(getApplicationContext(),editTextInputForAnswer,Toast.LENGTH_SHORT).show(); 
      } 


      Poll poll = new Poll(mCreatePollQuestion.getText().toString(), resultImageURL, mPollAnswers); 
      Map<String, Object> pollMap = poll.toMap(); 
      final String key = mBaseRef.child("Polls").push().getKey(); 
      Map<String, Object> childUpdates = new HashMap<String, Object>(); 
      childUpdates.put("/Polls/" + key, pollMap); 

      mBaseRef.updateChildren(childUpdates); 
      Collections.reverse(mPollAnswers); 
      for (int i = 0; i < mPollAnswers.size(); i++) { 
       mBaseRef.child("Polls").child(key).child("answers").child(String.valueOf(i + 1)).updateChildren(poll.answerConvert(mPollAnswers, i)); 
      } 

      Intent toHomeActivity = new Intent(CreateActivity.this, HomeActivity.class); 
      toHomeActivity.putExtra("viewpager_position", 2); 
      startActivity(toHomeActivity); 
     } 
    }); 

Wo ich von Firebase lesen und füllen Sie eine RecyclerView:

public class LiveFragment extends Fragment { 
// TODO: Rename parameter arguments, choose names that match 
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER 
private static final String ARG_PARAM1 = "param1"; 
private static final String ARG_PARAM2 = "param2"; 

private RecyclerView mRecyclerview; 
private DatabaseReference mBaseRef; 
private DatabaseReference mPollsRef; 
private LinearLayoutManager mLayoutManager; 
private FloatingActionButton mFloatingActionAdd; 

private FirebaseRecyclerAdapter<Poll, PollHolder> mFireAdapter; 

private RecyclerView.ItemAnimator mItemAnimator; 


// TODO: Rename and change types of parameters 
private String mParam1; 
private String mParam2; 

private OnFragmentInteractionListener mListener; 

public LiveFragment() { 
    // Required empty public constructor 
} 

/** 
* Use this factory method to create a new instance of 
* this fragment using the provided parameters. 
* 
* @param param1 Parameter 1. 
* @param param2 Parameter 2. 
* @return A new instance of fragment LiveFragment. 
*/ 
// TODO: Rename and change types and number of parameters 
public static LiveFragment newInstance(String param1, String param2) { 
    LiveFragment fragment = new LiveFragment(); 
    Bundle args = new Bundle(); 
    args.putString(ARG_PARAM1, param1); 
    args.putString(ARG_PARAM2, param2); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mBaseRef = FirebaseDatabase.getInstance().getReference(); 
    mPollsRef = mBaseRef.child("Polls"); 

    if (getArguments() != null) { 
     mParam1 = getArguments().getString(ARG_PARAM1); 
     mParam2 = getArguments().getString(ARG_PARAM2); 

    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    final View v = inflater.inflate(R.layout.fragment_new, container, false); 
    Log.v("TAG", "ON CREATE CALLED FROM NEW"); 

    mRecyclerview = (RecyclerView) v.findViewById(R.id.list); 
    mRecyclerview.setItemAnimator(new SlideInLeftAnimator()); 


    mLayoutManager = new LinearLayoutManager(getContext()); 
    mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    mLayoutManager.setReverseLayout(true); 
    mLayoutManager.setStackFromEnd(true); 

    mFloatingActionAdd = (FloatingActionButton) getActivity().findViewById(R.id.myFAB); 
    mFloatingActionAdd.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent I = new Intent(getActivity().getApplicationContext(), CreateActivity.class); 
      startActivity(I); 
     } 
    }); 


    mRecyclerview.setLayoutManager(mLayoutManager); 
    return v; 
} 

// TODO: Rename method, update argument and hook method into UI event 
public void onButtonPressed(Uri uri) { 
    if (mListener != null) { 
     mListener.onFragmentInteraction(uri); 
    } 
    scrollToPosition(); 
} 

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

    mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(Poll.class, R.layout.latest_item, PollHolder.class, mBaseRef.child("Polls")) { 
     @Override 
     protected void populateViewHolder(PollHolder viewHolder, final Poll model, final int position) { 
      viewHolder.mPollQuestion.setText(model.getQuestion()); 
      Picasso.with(getActivity().getApplicationContext()) 
        .load(model.getImage_URL()) 
        .fit() 
        .into(viewHolder.mPollImage); 
      viewHolder.mView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        Log.v("TAG", model.toString()); 
        Log.v("TAG","ONCLICKED"); 
        Intent toPoll = new Intent(getActivity(), PollHostActivity.class); 
        toPoll.putExtra("POLL_ID", mFireAdapter.getRef(position).getKey()); 
        startActivity(toPoll); 

       } 
      }); 
      Log.v("TAG", mFireAdapter.getRef(position).getKey()); 
      Log.v("TAG", String.valueOf(position)); 
      Log.v("TAG", model.getQuestion()); 
      Log.v("TAG", model.getImage_URL()); 
     } 
    }; 

    mRecyclerview.setAdapter(mFireAdapter); 
    scrollToPosition(); 



} 

@Override 
public void onStop() { 
    super.onStop(); 
    if (mFireAdapter != null) { 
     mFireAdapter.cleanup(); 
    } 
} 


@Override 
public void onDetach() { 
    super.onDetach(); 
    mListener = null; 
} 


public static class PollHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

    TextView mPollQuestion; 
    ImageView mPollImage; 
    View mView; 


    public PollHolder(View itemView) { 
     super(itemView); 

     mPollQuestion = (TextView) itemView.findViewById(R.id.latest_item_question); 
     mPollImage = (ImageView) itemView.findViewById(R.id.pollThumbNailImage); 
     this.mView = itemView; 
     itemView.setOnClickListener(this); 

    } 

    @Override 
    public void onClick(View view) { 
     Log.v("TAG", "CLICKED"); 
    } 
} 


private void scrollToPosition(){ 
    mFireAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { 
     @Override 
     public void onItemRangeInserted(int positionStart, int itemCount) { 
      super.onItemRangeInserted(positionStart, itemCount); 
      int pollCount = mFireAdapter.getItemCount(); 
      int lastVisiblePosition = mLayoutManager.findLastCompletelyVisibleItemPosition(); 

      // If the recycler view is initially being loaded or the user is at the bottom of the list, scroll 
      // to the bottom of the list to show the newly added message. 
      if (lastVisiblePosition == -1 || 
        (positionStart >= (pollCount - 1) && lastVisiblePosition == (positionStart - 1))) { 
       mRecyclerview.scrollToPosition(positionStart); 
      } 
     } 
    }); 
    } 
} 

Meine Gedanken:

  1. rufe ich mFireAdapter.cleanup() an der richtigen Stelle auf?

  2. Das Problem mit dem Klicken "8" und sehen "1" erscheint nicht auf der ersten Ladung des RecyclerView, es passiert nur, wenn ich von der Aktivität (zweites Bild) gehen und die zurück zum RecyclerView navigieren.

  3. Ich rufe .setStackFromEnd (true) und .setReverseLayout (true) auf, um die Daten umzukehren, wie sie in der FirebaseDatabase gespeichert sind, was zu dem Problem beitragen könnte.

  4. ich die .setOnClickListener() in der .populateViewHolder() Methode auf, und verwende die nach der .push Taste() in der Absicht, auf die nächste Aktivität zu übergeben:

    toPoll.putExtra("POLL_ID", mFireAdapter.getRef(position).getKey()); 
    

Diese Methode könnte den falschen Schlüssel erhalten.

Schließlich Firebase Datenbank:

enter image description here

Jede mögliche Hilfe würde geschätzt!

+1

versuchen, 'position' durch' holder.getAdapterPosition() ' – koceeng

+0

zu ersetzen Möchten Sie als Antwort machen? Scheint, für jetzt zu arbeiten ... – tccpg288

+0

Auch veröffentlicht auf Github: https://github.com/firebase/FirebaseUI-Android/issues/480 –

Antwort

1

Sie sollten position nicht außerhalb von populateViewHolder verwenden, da der Wert davon abweichen kann. Stattdessen machen Sie Ihre viewHolder endgültig und verwenden Sie viewHolder.getAdapterPosition(), um es zu ersetzen.

+0

Wo/wie würde ich es endgültig machen? – tccpg288

+0

in Ihrem 'protected void populateViewHolder (PollHolder viewHolder, endgültiges Poll-Modell, final int-Position)', machen Sie '... (final PollHolder viewHolder, ...' – koceeng

+0

Verstanden, habe nicht bemerkt, dass ich den Code der Firebase UI ändern könnte. – tccpg288

Verwandte Themen