cymcsg / cymcsg/UltimateRecyclerView

items in RecyclerView not displaying after filling

Open
#445 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
7.2k
Forks
1.4k
PR merge metrics
No merged PRs in 30d

Description

after filling the List (correctly filled as my Log shows), the adapter is not displaying the items. I don´t know why.

I read that it´s better to use the special "notify..." methods instead of adapter.notifyDataSetChanged() like adapter.notifyItemInserted(position)...i have done (i hope correctly), but it still shows nothing. i hope you can help me...

(The calling from Obejcts and inserting into the list works properly...and i´m not getting any error after running the app, just the Items are not showing)

**DATA Model (User)**

```
public class User {

public String name;
public String lastMessage;
public ParseObject image;

//Konstruktor
public User(String name, String lastMessage, ParseObject image) {
this.name = name;
this.lastMessage = lastMessage;
this.image = image;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getLastMessage() {
return lastMessage;
}

public void setLastMessage(String lastMessage) {
this.lastMessage = lastMessage;
}

public ParseObject getImage() {
return image;
}

public void setImage(ParseObject image) {
this.image = image;
}
}
```

**Adapter**

```
public class UserListAdapter extends SwipeableUltimateViewAdapter {
public UserListAdapter(List items) {
super(items);
}

//iwas internes
@Override
protected int getNormalLayoutResId() {
return DVHolder.layout;
}

//UltimateRecyclerView interaktionen
@Override
protected UltimateRecyclerviewViewHolder newViewHolder(final View view) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Click", Toast.LENGTH_SHORT).show();
}
});

final DVHolder dvHolder = new DVHolder(view, true);
dvHolder.swipeLayout.setOnDoubleClickListener(new SwipeLayout.DoubleClickListener() {
@Override
public void onDoubleClick(SwipeLayout layout, boolean surface) {
Toast.makeText(view.getContext(), "DoubleClick", Toast.LENGTH_SHORT).show();
}
});

dvHolder.deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
removeAt(dvHolder.getPosition());
Toast.makeText(view.getContext(), "Deleted " + dvHolder.getPosition(), Toast.LENGTH_SHORT).show();
}
});

dvHolder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), ""+dvHolder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});

return dvHolder;
}

@Override //Liste mit Daten füllen
protected void withBindHolder(UltimateRecyclerviewViewHolder holder, User user, int position) {
super.withBindHolder(holder, user, position);
((DVHolder) holder).name.setText(user.name);
((DVHolder) holder).lastMessage.setText(user.lastMessage);
//Das ParseFile (Image) wird nachher in der UserListActivity per Code geholt und zum ImageView hinzugefügt

}

//das so lassen
@Override
public DVHolder newFooterHolder(View view) {
return new DVHolder(view, false);
}

//das so lassen
@Override
public DVHolder newHeaderHolder(View view) {
return new DVHolder(view, false);
}

//Views etc. anlegen und zuweisen
public static class DVHolder extends UltimateRecyclerviewViewHolder {
public static final int layout = R.layout.user_item;
public TextView name;
public TextView lastMessage;
public ImageView userImage;

public Button deleteButton;
public LinearLayout linearLayout;
public SwipeLayout swipeLayout;

public DVHolder(View itemView, boolean bind) {
super(itemView);
if (bind) {
name = (TextView) itemView.findViewById(R.id.nameTV);
lastMessage = (TextView) itemView.findViewById(R.id.lastMessageTV);
userImage = (ImageView) itemView.findViewById(R.id.userImageIV);

deleteButton = (Button) itemView.findViewById(R.id.delete);
linearLayout = (LinearLayout) itemView.findViewById(R.id.linearLayout);

//diese standardmäßig so lassen, wenn Du swipe willst...
swipeLayout = (SwipeLayout) itemView.findViewById(R.id.recyclerview_swipe);
swipeLayout.setDragEdge(SwipeLayout.DragEdge.Right);
swipeLayout.setShowMode(SwipeLayout.ShowMode.PullOut);
}
}
}
}
```

**UserListActivity**
```

public class UserListActivity extends AppCompatActivity {

private UserListAdapter adapter;
private List userList;
private ScrollSmoothLineaerLayoutManager mLayoutManager;
protected UltimateRecyclerView ultimateRecyclerView;

ParseObject image;

final private int REQUEST_CODE_ASK_PERMISSION = 123; //kann jegliche Zahl sein. Wir benutzens halt später

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

// FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
// fab.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
// .setAction("Action", null).show();
// }
// });

image = null;

ultimateRecyclerView = (UltimateRecyclerView) findViewById(R.id.userList_ultimate_recycler_view);

userList = new ArrayList();
adapter = new UserListAdapter(userList);
adapter.setMode(SwipeItemManagerInterface.Mode.Single);
mLayoutManager = new ScrollSmoothLineaerLayoutManager(this, LinearLayoutManager.VERTICAL, false, 500);
ultimateRecyclerView.setLayoutManager(mLayoutManager);
ultimateRecyclerView.setAdapter(adapter);

// NICHT VERGESSEN DAS MANIFEST DIE PERMISSIONS EINZUTRAGEN !!! <----------------------------------

// wenn die Permission NICHT gegeben wurde... und was wir dann machen kommt in diesem Block
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){

if(ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)){

//Hier können wir eintragen, wieso wir eigentlich die Permission brauchen/verlangen
}else{

//Permission anfragen
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSION);
}
}
//---------------------------------------------------------------------------------------------

ParseQuery query = ParseUser.getQuery();

//Für Join <<<<---------
// query.whereMatchesKeyInQuery("Name der ID-Spalte hier", "Name der_FOREIGN_KEY-Spalte in der anderen Tabelle", query (der anderen Tabelle hier einfügen); Wir brauchen also query´s von den Tabellen und dann Matchen wir die Keys in den querys. Das kann man mit belieblig vielen Queries machen (also Joinen miteinander)!!!

if(ParseUser.getCurrentUser() != null){ //Wenn es einen User gibt, der eingeloggt ist.

query.whereNotEqualTo("username", ParseUser.getCurrentUser().getUsername()); //Query mit allen Nutzern OHNE mich selber. "username" ist hier die Spalte mit den Nutzer-Namen.
query.addAscendingOrder("username"); //Aufsteigend sortiert nach usernamen;

query.findInBackground(new FindCallback() {
@Override
public void done(List objects, ParseException e) {

if(e == null){

Log.i("andere User in DB", objects.size()+"");
Log.i("Liste vor befüllen", userList.size()+"");

if(objects.size() > 0){ // Wenn ich Objekte (Usernamen) habe in meiner Tabelle

/* for (int i = 0; i < objects.size(); i++) {
usernames.add(objects.get(i).getUsername());
}*/

// Alternative mit for-each-Schleife (ACHTUNG: Kann sein, dass du noch danach noch arrayadapter.notiyDataSetChanged() aufrufen musst! Teste es einfach mal ohne, ansonsten nach dem befüllen arrayadapter.notiyDataSetChanged(); aufrufen

/*for(ParseUser user: objects){
userList.add(new User(user.getUsername(), "lastMessage", image)); //TODO: Parsefile später als Image holen
}*/

for (int i = 0; i < objects.size(); i++) {
userList.add(new User(objects.get(i).getUsername(), "lastMessage", image)); //TODO: Parsefile später als Image holen
adapter.notifyItemInserted(i);
}

}

Log.i("Liste NACH befüllen", userList.size()+"");

}
}
});
}

//adapter.notifyDataSetChanged();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_user_list, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if(id == R.id.logout){
ParseUser.logOut();
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
}

return super.onOptionsItemSelected(item);

}
}
```

**XML FILES BELOW**

**content_user_list.xml**

```

```

**activity_user_list.xml**

```

```

**user_item.xml**
```




```

Thanks a lot!

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in UserListActivity at the ParseQuery callback, then inspect UserListAdapter and the referenced content_user_list.xml and user_item layout. Reproduce the empty list while checking the populated userList, adapter binding, and RecyclerView setup; done means the queried users visibly render in the list without errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
mobile-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.