Ich habe ein PopupWindow, das eine RecyclerView enthält. Das letzte Element von RecyclerView ist eine Schaltfläche, die am Ende der Liste des Adapters ein neues Element hinzufügt, wenn darauf geklickt wird.RecyclerView Elemente hinzugefügt mit notifyItemInserted nur angezeigt, nachdem die Ansicht neu geladen wurde
Das Problem: Während der ersten Zeit hat mein PopupWindow gestartet fügt die Schaltfläche erfolgreich neue Elemente in die RecyclerView mit notifyItemInserted(dataSize - 1)
, wenn darauf geklickt, aber die RecyclerView und sie zeigen nicht aktualisiert. Wenn ich das PopupWindow schließe und wieder öffne, werden die zuvor hinzugefügten Elemente ordnungsgemäß im RecyclerView und angezeigt. Es aktualisiert und animiert ordnungsgemäß neue Elemente, die dem Adapter hinzugefügt werden.
Die Frage: Ich bin mir nicht sicher, warum der RecyclerView nicht aktualisiert und die neu hinzugefügten Elemente beim ersten Start des PopupWindow zeigt, aber funktioniert perfekt ab dem zweiten Durchlauf. Wie mache ich es beim ersten Start des PopupWindow funktionieren?
P.S. Es ist erwähnenswert, dass, wenn ich notifyDataSetChanged()
verwende, der RecyclerView korrekt funktioniert (zeigt neue Elemente an), sogar beim ersten Start des PopupWindow. Ich möchte einen Weg finden, notifyItemInserted()
funktionieren zu lassen, weil es nette Animationen hat, wenn neue Elemente hinzugefügt werden.
UserChordsAdapter.java
public class UserChordsAdapter extends RecyclerView.Adapter<UserChordsAdapter.ChordViewHolder> {
private Context context;
private final ListItemClickListener mClickHandler;
private ArrayList<String> mChordData = new ArrayList<String>(); //contains all user created chords as comma delimited note #s
/**
* The interface that receives onClick messages.
*/
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
}
/**
*
* @param clickHandler The on-click handler for this adapter. This single handler is called
* when an item is clicked.
*/
public UserChordsAdapter(ListItemClickListener clickHandler) {
mClickHandler = clickHandler;
}
@Override
public ChordViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
context = parent.getContext();
int layoutIdForListItem = R.layout.user_chord_list_item;
int layoutIdForFooterItem = R.layout.user_chord_add_new;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View listItem;
ChordViewHolder viewHolder;
if (viewType == R.layout.user_chord_list_item) { //inflate chord item
listItem = inflater.inflate(layoutIdForListItem, parent, shouldAttachToParentImmediately);
viewHolder = new ChordViewHolder(listItem);
}
else { //inflate "+ Add new" button (last list item)
listItem = inflater.inflate(layoutIdForFooterItem, parent, shouldAttachToParentImmediately);
viewHolder = new ChordViewHolder(listItem);
}
return viewHolder;
}
@Override
public void onBindViewHolder(ChordViewHolder holder, int position) {
if (position == mChordData.size()){
holder.mAddChordButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
mChordData.add("1,30,40");
notifyItemInserted(mChordData.size()-1);
}
});
}
else {
holder.mChordName.setText("Chord " + Integer.toString(position));
}
}
@Override
public int getItemCount() {
if (mChordData == null){
return 1;
}
return mChordData.size() + 1; // +1 is for footer button (add new)
}
class ChordViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// Will display which ViewHolder is displaying this data
TextView mChordName;
Button mAddChordButton;
/**
* Constructor for our ViewHolder. Within this constructor, we get a reference to our
* TextViews and set an onClickListener to listen for clicks. Those will be handled in the
* onClick method below.
*/
public ChordViewHolder(View itemView) {
super(itemView);
mAddChordButton = (Button) itemView.findViewById(R.id.button_add_new);
mChordName = (TextView) itemView.findViewById(R.id.tv_view_holder_instance);
itemView.setOnClickListener(this);
}
/**
* Called whenever a user clicks on an item in the list.
* @param v The View that was clicked
*/
@Override
public void onClick(View v) {
int clickedPosition = getAdapterPosition();
String chordData = mChordData.get(clickedPosition);
mClickHandler.onListItemClick(clickedPosition);
}
}
/**
* Distinguishes if view is a Chord list item or the last item in the list (add new chord)
* @param position
* @return
*/
@Override
public int getItemViewType(int position) {
return (position == mChordData.size()) ? R.layout.user_chord_add_new : R.layout.user_chord_list_item;
}}
FragmentChordMenu.java
public class FragmentChordMenu extends Fragment implements UserChordsAdapter.ListItemClickListener{
private FloatingActionButton mFAB;
private View mPopupView;
private PopupWindow mUserChordMenu;
private RecyclerView mUserChordsList;
private UserChordsAdapter mRecyclerViewAdapter;
private int numItems = 0; //TODO: dynamically calculate this as # of saved chords + 1(add new)
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRecyclerViewAdapter = new UserChordsAdapter(this);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.menu_fragment_chord, container, false);
LayoutInflater layoutInflater = (LayoutInflater)getActivity().getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mPopupView = layoutInflater.inflate(R.layout.menu_popup_set_chords, null);
int menuWidth = (int)(MainActivity.getActualWidth()*.95);
int menuHeight = (int)(MainActivity.getActualHeight()*.90);
mUserChordMenu = new PopupWindow(mPopupView, menuWidth, menuHeight);
mUserChordMenu.setFocusable(true);
mFAB = (FloatingActionButton) v.findViewById(R.id.addChord);
mFAB.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mUserChordMenu.showAtLocation(mPopupView, Gravity.CENTER, 10, 10);
mUserChordsList = (RecyclerView) mPopupView.findViewById(R.id.rv_userChords);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mUserChordsList.setLayoutManager(layoutManager);
mUserChordsList.setAdapter(mRecyclerViewAdapter);
}
});
return v;
}
/**
* Called from UserChordsAdapter's onClick. Only fires on list item clicks, not the add new button
*
* */
@Override
public void onListItemClick(int clickedItemIndex) {
}}
Von welchen externen Änderungen leiten Sie ab? – Remario
Keine. Dies ist ein Proof of Concept für das Hinzufügen von Platzhalterelementen zu meiner RecyclerView, wenn auf eine Schaltfläche geklickt wird. – Cody
Warum haben Sie das Benachrichtigungsupdate notifyItemInserted (mChordData.size() - 1); in onBind? – Remario