This question already has answers here:
recyclerview No adapter attached; skipping layout
(38 answers)
RecyclerView﹕ No adapter attached; skipping layout
(3 answers)
E/RecyclerView: No adapter attached; skipping layout (Using FRAGMENTS)
(2 answers)
"RecyclerView: No Adapter attached; skipping layout" for recyclerview in fragment [duplicate]
(3 answers)
Closed 1 year ago.
I'm trying to show all user posts that the user who is using the app follows, and I'm using Firestore. I take all the ids and put them on an arraylist and build a query. I am using FirebaseRecyclerView but I have this error:
2021-06-13 16:33:29.177 22744-22744/com.conta.pophome E/RecyclerView: No adapter attached; skipping layout
I don't think it's an error due to the java code (I'm not fully sure, but I think it is) but I think it's due to the graphics (xml).
graphic code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primaryPopHome"
android:minHeight="?attr/actionBarSize"
android:theme="#style/AppTheme.bar">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:scaleType="centerInside"
android:src="#drawable/poplogo"
/>
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="300dp"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="1.9"
app:cardCornerRadius="80dp">
<ImageView
android:id="#+id/img_profilomain"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:backgroundTint="#color/white"
android:scaleType="centerCrop"
/>
</androidx.cardview.widget.CardView>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/add_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:src="#drawable/poplike"
android:backgroundTint="#color/redButton2"
app:borderWidth="0dp"
app:fabSize="normal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!--Floating action button for add alarm-->
<!--Make sure that you are constraining this
button to the parent button-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/add_alarm_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
app:fabSize="normal"
app:layout_constraintBottom_toTopOf="#+id/add_fab"
app:layout_constraintEnd_toEndOf="#+id/add_fab"
app:layout_constraintStart_toStartOf="#+id/add_fab"
app:srcCompat="#drawable/ic_baseline_add_24"
app:borderWidth="0dp"
android:backgroundTint="#color/redButton2"
/>
<!--Action name text for the add alarm button-->
<!--Make sure that you are constraining this Text to
the add Alarm FAB button-->
<TextView
android:id="#+id/add_alarm_action_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="Crea Post"
app:layout_constraintBottom_toBottomOf="#+id/add_alarm_fab"
app:layout_constraintEnd_toStartOf="#+id/add_alarm_fab"
app:layout_constraintTop_toTopOf="#+id/add_alarm_fab" />
<!--Floating action button for add person-->
<!--Make sure that you are constraining this
button to the add Alarm FAB button-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/add_person_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
app:fabSize="normal"
app:layout_constraintBottom_toTopOf="#+id/add_alarm_fab"
app:layout_constraintEnd_toEndOf="#+id/add_alarm_fab"
app:layout_constraintStart_toStartOf="#+id/add_alarm_fab"
app:srcCompat="#drawable/ic_baseline_search_24"
app:borderWidth="0dp"
android:backgroundTint="#color/redButton2"
/>
<!--Action name text for the add person button-->
<!--Make sure that you are constraining this Text
to the add Person FAB button-->
<TextView
android:id="#+id/add_person_action_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="Cerca utenti"
app:layout_constraintBottom_toBottomOf="#+id/add_person_fab"
app:layout_constraintEnd_toStartOf="#+id/add_person_fab"
app:layout_constraintTop_toTopOf="#+id/add_person_fab" />
<Button
android:id="#+id/btn_logout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="152dp"
android:text="Logout"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/appBarLayout"
app:layout_constraintVertical_bias="0.111" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcViewPostMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout"
tools:layout_editor_absoluteX="-16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
and this is the java code:
public class MainActivity extends AppCompatActivity {
private FirebaseAuth fAuth;
private DatabaseReference dbRef;
private DatabaseReference uri;
private RecyclerView findPost;
FloatingActionButton mAddFab, mAddAlarmFab, mAddPersonFab;
// These are taken to make visible and invisible along
// with FABs
TextView addAlarmActionText, addPersonActionText;
// to check whether sub FAB buttons are visible or not.
Boolean isAllFabsVisible;
private ArrayList<String> Uidrecord = new ArrayList<>();
private ArrayList<String> uidFollowing = new ArrayList<>();
/*
private String [] Uidrecord = new String[1000];
private String[] uidFollowing = new String[1000];*/
int cont = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
overridePendingTransition(0, 0);
findPost = findViewById(R.id.rcViewPostMain);
fAuth = FirebaseAuth.getInstance();
// Register all the FABs with their IDs
// This FAB button is the Parent
mAddFab = findViewById(R.id.add_fab);
// FAB button
mAddAlarmFab = findViewById(R.id.add_alarm_fab);
mAddPersonFab = findViewById(R.id.add_person_fab);
// Also register the action name text, of all the FABs.
addAlarmActionText = findViewById(R.id.add_alarm_action_text);
addPersonActionText = findViewById(R.id.add_person_action_text);
// Now set all the FABs and all the action name
// texts as GONE
mAddAlarmFab.setVisibility(View.GONE);
mAddPersonFab.setVisibility(View.GONE);
addAlarmActionText.setVisibility(View.GONE);
addPersonActionText.setVisibility(View.GONE);
// make the boolean variable as false, as all the
// action name texts and all the sub FABs are invisible
isAllFabsVisible = false;
// We will make all the FABs and action name texts
// visible only when Parent FAB button is clicked So
// we have to handle the Parent FAB button first, by
// using setOnClickListener you can see below
mAddFab.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!isAllFabsVisible) {
// when isAllFabsVisible becomes
// true make all the action name
// texts and FABs VISIBLE.
mAddAlarmFab.show();
mAddPersonFab.show();
addAlarmActionText.setVisibility(View.VISIBLE);
addPersonActionText.setVisibility(View.VISIBLE);
// make the boolean variable true as
// we have set the sub FABs
// visibility to GONE
isAllFabsVisible = true;
} else {
// when isAllFabsVisible becomes
// true make all the action name
// texts and FABs GONE.
mAddAlarmFab.hide();
mAddPersonFab.hide();
addAlarmActionText.setVisibility(View.GONE);
addPersonActionText.setVisibility(View.GONE);
// make the boolean variable false
// as we have set the sub FABs
// visibility to GONE
isAllFabsVisible = false;
}
}
});
// below is the sample action to handle add person
// FAB. Here it shows simple Toast msg. The Toast
// will be shown only when they are visible and only
// when user clicks on them
mAddPersonFab.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, ricerca.class));
}
});
// below is the sample action to handle add alarm
// FAB. Here it shows simple Toast msg The Toast
// will be shown only when they are visible and only
// when user clicks on them
mAddAlarmFab.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, posta.class));
}
});
if(fAuth.getCurrentUser() == null) {
startActivity(new Intent(MainActivity.this, accesso.class));
return;
}
ImageView img_profilo = findViewById(R.id.img_profilomain);
dbRef = FirebaseDatabase.getInstance().getReference("Users");
uri = dbRef.child(fAuth.getCurrentUser().getUid()).child("url");
Button btn_logout = findViewById(R.id.btn_logout);
btn_logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fAuth.signOut();
startActivity(new Intent(MainActivity.this, accesso.class));
}
});
showImage();
FirebaseFirestore.getInstance().collection("following").document(FirebaseAuth.getInstance().getCurrentUser().getUid()).collection("userFollowing").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
document.getData();
Uidrecord.add(cont,String.valueOf(document.getData()));
cont++;
}
int conta = 0;
for (String item: Uidrecord){
if(item == null)
break;
uidFollowing.add(conta,getFollowingUid(item));
Toast.makeText(MainActivity.this, uidFollowing.get(conta), Toast.LENGTH_SHORT).show();
conta++;
}
} else {
Toast.makeText(MainActivity.this, task.getException().toString(), Toast.LENGTH_SHORT).show();
}
}
});
findPost.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
onStart();
}
#Override
protected void onStart() {
super.onStart();
Query query = FirebaseFirestore.getInstance()
.collection("post/" + uidFollowing + "/userPosts")
.limit(1000);
FirestoreRecyclerOptions<GetInfoPost> options = new FirestoreRecyclerOptions.Builder<GetInfoPost>()
.setQuery(query, GetInfoPost.class)
.build();
FirestoreRecyclerAdapter<GetInfoPost, FindFriendsViewHolder> firestoreRecyclerAdapter = new FirestoreRecyclerAdapter<GetInfoPost, FindFriendsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull FindFriendsViewHolder holder, int position, #NonNull GetInfoPost model) {
holder.txtTitoloInPost.setText(model.getTitle() + " " + model.getValutation() + "/10");
holder.txtData.setText(model.getdate());
Picasso.get().load(model.getUrlImage()).into(holder.imgPost);
holder.txtDescrizione.setText(model.getDescription());
holder.txtTag.setText(model.getGenre());
}
#NonNull
#Override
public FindFriendsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.post, parent, false);
return new FindFriendsViewHolder(view);
}
};
findPost.setAdapter(firestoreRecyclerAdapter);
firestoreRecyclerAdapter.startListening();
}
public static class FindFriendsViewHolder extends RecyclerView.ViewHolder {
TextView nameInPost, txtData, txtTag, txtTitoloInPost, txtLikenmb, txtDescrizione;
ImageView img_profinPost, imgPost, imgLike;
RelativeLayout cardView;
GifImageView gifLike;
public FindFriendsViewHolder(#NonNull View itemView) {
super(itemView);
nameInPost = itemView.findViewById(R.id.nameInPost);
txtData = itemView.findViewById(R.id.txtData);
txtTag = itemView.findViewById(R.id.txtTag);
txtTitoloInPost = itemView.findViewById(R.id.txtTitoloInPost);
txtLikenmb = itemView.findViewById(R.id.txtLikenmb);
txtDescrizione = itemView.findViewById(R.id.txtDescrizione);
img_profinPost = itemView.findViewById(R.id.img_profinPost);
imgPost = itemView.findViewById(R.id.imgPost);
cardView = itemView.findViewById(R.id.card_viewR);
gifLike = itemView.findViewById(R.id.gifLike);
imgLike = itemView.findViewById(R.id.imgLike);
}
}
#Override
public void onBackPressed() {
}
private void showImage() { //mostro l'immagine usando picasso con l'url nel child url del profilo
ImageView img_prof = findViewById(R.id.img_profilomain);
uri.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String url = snapshot.getValue(String.class);
// Toast.makeText(getApplicationContext(), url, Toast.LENGTH_SHORT).show();
Picasso.get().load(url).into(img_prof);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private String getFollowingUid(String result){
int stringLength = result.length();
String tmp = result.substring(7, stringLength-1);
return tmp;
}
}
I tried to read the other similar questions but could not pinpoint the cause of my problem.
Would you help me understand what I'm doing wrong?
Edits:
I tried putting the recycler view adapter in onCreate but it still doesn't work -> https://codeshare.io/wndbEB
You need to set your recyclerView on the main thread. Try to put the recyclerView in onCreate() and the .startListening() in the onStart.
Related
I asked about this yesterday but never had much luck, I thought I would re-ask with a clearer outline of what I am trying to do..
Firstly, here is my Firebase hierarchy
I have a RecyclerViewAdapter/View which finds the Uid, and if the user has dogs listed on their 'account' then it will display a list of dogs, in this case finn and moo, this section is my first activity - ChooseDog. Each dog is clickable, and after clicking, it will take you to the second activity - DogProfile - where I am displaying details from each particular dog.
My problem is that the profile is only picking a random dog (if there is more than one) and displaying those details, I cannot seem to differentiate the results.
I want to take the name displayed on the card/button on ChooseDog, send it to the DogProfile via an intent, then use that name to show the correct details for the chosen dog. I'm quite new to this, but feel like I've done everything somewhat correctly? Any help is appreciated. I have been able to find the details when declaring the name explicitly, but not when trying to retrieve the name from the card.
ChooseDog (1st Activity)
TextView dogName;
databaseReference = FirebaseDatabase.getInstance().getReference("user").child(uid).child("dogs");
dogName = findViewById(R.id.dogName);
ItemClickSupport.addTo(recyclerView).setOnItemClickListener(
new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
getDogData();
Intent intent = new Intent(ChooseDog.this, DogProfile.class);
intent.putExtra("name", dogName.getText().toString());
startActivity(intent);
}
}
);
private void getDogData() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String dogName = ds.child("name").getValue(String.class);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
}
DogProfile (2nd Activity)
private void getDogData() {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("user").child(uid).child("dogs");
String dogsName = getIntent().getExtras().getString("name");
Query query = databaseReference.orderByChild("name").equalTo(dogsName);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
String dogBreed = ds.child("breed").getValue(String.class);
String dogAge = ds.child("age").getValue(String.class);
String gender = ds.child("gender").getValue(String.class);
String dogWeight = ds.child("weight").getValue(String.class);
String neutered = ds.child("neutered").getValue(String.class);
dogName.setText(name);
breed.setText(dogBreed);
age.setText(dogAge);
dogGender.setText(gender);
weight.setText(dogWeight);
isNeutered.setText(neutered);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
}
Logcat
2021-07-29 10:13:49.990 17941-17941/com.example.doggo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.doggo, PID: 17941
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference
at com.example.doggo.ChooseDog$1.onItemClicked(ChooseDog.java:69)
at com.example.doggo.ItemClickSupport$1.onClick(ItemClickSupport.java:16)
at android.view.View.performClick(View.java:8160)
at android.view.View.performClickInternal(View.java:8137)
at android.view.View.access$3700(View.java:888)
at android.view.View$PerformClick.run(View.java:30236)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8512)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1139)
This answer based on your last few questions , hope this will help you. Today I will not talk about firebase authentication or store data part , because you already done that . I understand that at first you want to retrieve data and want show it in RecyclerView , then if user click on these specific data/item you want to show details through DogProfile. Almost of your code fine , in getDogData() method you should just add dogName with ArrayList and populate the Adapter . Then pass the data trough intent , use adapter.getItem(position) instead dogName variable.
Just follow these code-
ChooseDog class
public class ChooseDog extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
MyRecyclerViewAdapter adapter;
private DatabaseReference databaseReference;
private ArrayList<String> dogList;
private String dogName;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_dog);
// dogName = findViewById(R.id.dogName);
databaseReference = FirebaseDatabase.getInstance().getReference("user").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("dogs");
getDogData();
dogList = new ArrayList<>();
recyclerView = findViewById(R.id.dogList);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapter = new MyRecyclerViewAdapter(getApplicationContext(), dogList);
adapter.setClickListener(this);
}
private void getDogData() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
dogName = ds.child("name").getValue().toString();
dogList.add(dogName);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
}
#Override
public void onItemClick(View view, int position) {
Toast.makeText(this, "You Selected " + adapter.getItem(position), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ChooseDog.this, DogProfile.class);
intent.putExtra("name", adapter.getItem(position));
startActivity(intent);
}
}
activity_choose_do.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChooseDog">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/dogList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MyRecyclerViewAdapter class
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private List<String> zData;
private LayoutInflater zInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
MyRecyclerViewAdapter(Context context, List<String> data) {
this.zInflater = LayoutInflater.from(context);
this.zData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = zInflater.inflate(R.layout.recyclerview_layout, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String dog = zData.get(position);
holder.myTextView.setText(dog);
}
// total number of rows
#Override
public int getItemCount() {
return zData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.dogsName);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return zData.get(id);
}
// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
recyclerview_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="#+id/dogsName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"/>
DogProfile class , in this some wrong cast I was found , such as Spinner as TextView . Here fixed copy -
public class DogProfile extends AppCompatActivity {
private FirebaseAuth firebaseAuth;
private FirebaseUser currentUser;
TextView breed;
Spinner ageDropdown, genderDropdown, weightDropdown, neuteredDropdown; //zi
String uid;
String dogId;
private EditText dogName; //zi
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dog_profile);
firebaseAuth = FirebaseAuth.getInstance();
currentUser = firebaseAuth.getCurrentUser();
uid = currentUser.getUid();
dogName = findViewById(R.id.name);
breed = findViewById(R.id.breed);
ageDropdown = findViewById(R.id.age);
genderDropdown= findViewById(R.id.gender);
weightDropdown = findViewById(R.id.weight);
neuteredDropdown = findViewById(R.id.neutered);
getDogData();
}
private void getDogData() {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("user").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("dogs");
String dogsName = getIntent().getExtras().getString("name");
Query query = databaseReference.orderByChild("name").equalTo(dogsName);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String name = (String) ds.child("name").getValue();
if (name.equals(dogsName)) {
String dogBreed = (String) ds.child("breed").getValue();
String dogAge = (String) ds.child("age").getValue();
String gender = (String) ds.child("gender").getValue();
String dogWeight = (String) ds.child("weight").getValue();
String neutered = (String) ds.child("neutered").getValue();
dogName.setText(name);
breed.setText(dogBreed);
ArrayAdapter<String> ageAdapter = new ArrayAdapter<String> (getApplicationContext(), android.R.layout.simple_spinner_item, Collections.singletonList(dogAge));
ageAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
ageDropdown.setAdapter(ageAdapter);
ArrayAdapter<String> weightAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, Collections.singletonList(dogWeight));
weightAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
weightDropdown.setAdapter(weightAdapter);
ArrayAdapter<String> genderAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, Collections.singletonList(gender));
genderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
genderDropdown.setAdapter(genderAdapter);
ArrayAdapter<String> neuteredAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, Collections.singletonList(neutered));
neuteredAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
neuteredDropdown.setAdapter(neuteredAdapter);
} else {
Toast.makeText(DogProfile.this, "Please try again..", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
}
}
dog_profile.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DogProfile">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayout"
android:layout_width="0dp"
android:layout_height="560dp"
android:layout_marginStart="9dp"
android:layout_marginLeft="9dp"
android:layout_marginEnd="9dp"
android:layout_marginRight="9dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Spinner
android:id="#+id/age"
android:layout_width="160dp"
android:layout_height="59dp"
android:autofillHints="age"
android:hint="Age"
android:inputType="text"
android:labelFor="#+id/name"
android:spinnerMode="dropdown"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.085"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.353" />
<Spinner
android:id="#+id/weight"
android:layout_width="160dp"
android:layout_height="61dp"
android:autofillHints="weight"
android:hint="Weight (kg)"
android:inputType="text"
android:labelFor="#+id/name"
android:spinnerMode="dropdown"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.901"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.356" />
<TextView
android:id="#+id/breed"
android:layout_width="347dp"
android:layout_height="57dp"
android:autofillHints="breed"
android:focusable="true"
android:hint="Breed"
android:inputType="text"
android:labelFor="#+id/name"
android:spinnerMode="dropdown"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.434"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.196" />
<EditText
android:id="#+id/name"
android:layout_width="354dp"
android:layout_height="56dp"
android:autofillHints="Name"
android:hint="Name"
android:inputType="text"
android:labelFor="#+id/name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.032" />
<Spinner
android:id="#+id/gender"
android:layout_width="160dp"
android:layout_height="61dp"
android:autofillHints="gender"
android:hint="Gender"
android:inputType="text"
android:labelFor="#+id/name"
android:spinnerMode="dropdown"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.086"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.532" />
<Spinner
android:id="#+id/neutered"
android:layout_width="160dp"
android:layout_height="56dp"
android:autofillHints="neutered"
android:hint="Neutered?"
android:inputType="text"
android:labelFor="#+id/name"
android:spinnerMode="dropdown"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.901"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.535" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Daily Exercise Goal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.058"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.665" />
<View
android:id="#+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.624" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
ok, I have a custom adapter which will display exercise, time, and whether the exercise is selected or not. When the user clicks on the clock icon inside every element in the adapter a dialogbox will show up, in which the user can modify the time for exercise. Once the time is entered the arraylist containing objects of type exercise will be updated. so the exerciseTime for that exercise object inside the list will be updated. Then the list will be refresh and the new exercise time will be displayed. but that is not the case. I can get the time to be updated. when I first create the arraylist of exercises, which I get from string.xml resource file, the default exercise time is 30min. but after the user updates, is still reflecting the time. any help apprciated.
entry_item.xml for custom adapter
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/backroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp">
<ImageView
android:id="#+id/item_icon_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.10"
android:src="#drawable/ic_running_exercise"/>
<TextView
android:id="#+id/exercise_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.40"
android:textSize="20sp"
android:textColor="#color/textColor"
android:text="Running"/>
<TextView
android:id="#+id/exercise_time_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.20"
android:textSize="18sp"
android:textColor="#color/textColor"
android:text="30 min"/>
<ImageView
android:layout_gravity="center"
android:id="#+id/set_time_imagview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.20"
android:src="#drawable/ic_timer_black_24dp"/>
<CheckBox
android:id="#+id/exercise_checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.05"
android:buttonTint="#color/textColor"/>
</LinearLayout>
</RelativeLayout>
custom adapter
public class WorkoutAdapter extends ArrayAdapter<Exercise> {
public WorkoutAdapter(Context context, int num, ArrayList<Exercise> exerciseList) {
super(context, 0, exerciseList);
// allExercises = exerciseList;
}
#NonNull
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// Get the data item for this position
final Exercise exercise = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.entry_item, parent, false);
}
// Lookup view for data population
ImageView exerciseImageview = convertView.findViewById(R.id.item_icon_imageview);
TextView exerciseNameTextview = convertView.findViewById(R.id.exercise_textview);
TextView exerTimeTextview = convertView.findViewById(R.id.exercise_time_textview);
final ImageView setTimeImageview = convertView.findViewById(R.id.set_time_imagview);
final CheckBox exerciseCheckbox = convertView.findViewById(R.id.exercise_checkBox);
exerciseNameTextview.setText(exercise.getExerciseName());
exerciseImageview.setImageResource(exercise.getExerciseImage());
//selected exercise checkbox
exerciseCheckbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(exerciseCheckbox.isChecked()) {
exercise.setSelected(true);
}
else {
exercise.setSelected(false);
}
}
});
setTimeImageview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setTimerDialogBox(position);
Toast.makeText(getContext(), position+"", Toast.LENGTH_LONG).show();
}
});
return convertView;
}
/**
* alert dialogbox for add new item to listview
*/
private void setTimerDialogBox(final int position) {
// Creating alert Dialog with one Button
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext(), R.style.dialogBox);
alertDialog.setTitle("Set Time");
final EditText input = new EditText(getContext());
alertDialog.setView(input);
alertDialog.setIcon(R.drawable.ic_timer_black_24dp1);
alertDialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
long time = Long.parseLong(input.getText().toString());
Workout.exerciseList.get(position).setExerciseTime(time);
notifyDataSetChanged();
Toast.makeText(getContext(),"Time added", Toast.LENGTH_SHORT).show();
}
}).create();
alertDialog.setNegativeButton("CANCEL",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).create();
alertDialog.show();
}
}
I am still learning android. Here I need help to toggle between Play and Pause source in ImageButton in the ListView.
There should be only one song in Play state at a time. So if clicked other should stop.
SongAdapter.java
public class SongAdapter extends ArrayAdapter<Song> {
public SongAdapter(#NonNull Context context, int resource, #NonNull List<Song> objects) {
super(context, resource, objects);
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View playlistItemView = convertView;
if (playlistItemView == null) {
playlistItemView = LayoutInflater.from(getContext()).inflate(R.layout.playlist_item, parent, false);
}
Song currentSong = getItem(position);
// get list item elements
ImageView albumCoverThumbnail = playlistItemView.findViewById(R.id.playlist_album_thumbnail);
TextView songTitle = playlistItemView.findViewById(R.id.playlist_song_title);
TextView songAlbumTitle = playlistItemView.findViewById(R.id.playlist_song_album_title);
TextView songArtist = playlistItemView.findViewById(R.id.playlist_song_artist);
final ImageButton songPlayButton = playlistItemView.findViewById(R.id.playlist_play_button);
// set data to the list item
assert currentSong != null;
albumCoverThumbnail.setImageResource(currentSong.getSongAlbumCoverId());
songTitle.setText(currentSong.getSongTitle());
songAlbumTitle.setText(currentSong.getSongAlbumTitle());
songArtist.setText(currentSong.getSongSingers());
// set song button action
songPlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
songPlayButton.setImageResource(R.drawable.ic_pause_black_24dp);
Toast.makeText(getContext(), "Button clicked for item " + position, Toast.LENGTH_LONG).show();
}
});
return playlistItemView;
}
}
Song.java
public class Song {
private String songAlbumTitle;
private String songTitle;
private String songSingers;
private int songAlbumCoverId;
public Song(String albumTitle, String title, String singers, int albumCoverId) {
songAlbumTitle = albumTitle;
songTitle = title;
songSingers = singers;
songAlbumCoverId = albumCoverId;
}
public String getSongAlbumTitle() {
return songAlbumTitle;
}
public String getSongTitle() {
return songTitle;
}
public String getSongSingers() {
return songSingers;
}
public int getSongAlbumCoverId() {
return songAlbumCoverId;
}
}
Activity.java
public class DreamVoyage extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dream_voyage);
// get view ids
ImageView albumCoverImage = findViewById(R.id.album_cover);
// get intent extras
Bundle bundle = getIntent().getExtras();
// check if bundle in not null and containing value
if (bundle != null) {
String albumTitle = bundle.getString("album_one_title");
String albumBand = bundle.getString("album_one_band");
int albumCover = bundle.getInt("album_one_cover");
albumCoverImage.setImageResource(albumCover);
TextView albumTitleText = findViewById(R.id.album_title);
TextView albumBandText = findViewById(R.id.album_band);
albumTitleText.setText(albumTitle);
albumBandText.setText(albumBand);
ArrayList<Song> songs = new ArrayList<Song>();
songs.add(new Song(albumTitle, "I do it for you", "Bryn Adams", albumCover));
songs.add(new Song(albumTitle, "Here I am", "Bryn Adams", albumCover));
SongAdapter songAdapter = new SongAdapter(this, 0, songs);
ListView listView = findViewById(R.id.playlist_view);
listView.setAdapter(songAdapter);
}
}
}
playlist_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="#drawable/border_bottom"
android:orientation="horizontal">
<ImageView
android:id="#+id/playlist_album_thumbnail"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="#drawable/album_three"
android:scaleType="centerCrop"
android:contentDescription="#string/album_thumbnail_desc"/>
<android.support.constraint.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:id="#+id/playlist_song_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mon voyage de rêve"
android:layout_marginLeft="8dp"
android:textColor="#000000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/playlist_song_album_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dream Voyage"
android:textSize="10sp"
android:textColor="#666666"
app:layout_constraintTop_toBottomOf="#+id/playlist_song_title"
app:layout_constraintStart_toStartOf="#id/playlist_song_title"/>
<TextView
android:id="#+id/playlist_song_credit_separator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" - "
android:textSize="10sp"
android:textColor="#666666"
app:layout_constraintTop_toBottomOf="#+id/playlist_song_title"
app:layout_constraintStart_toEndOf="#id/playlist_song_album_title"/>
<TextView
android:id="#+id/playlist_song_artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" - John Doen, Jane Doe"
android:textSize="10sp"
android:textColor="#666666"
app:layout_constraintTop_toBottomOf="#+id/playlist_song_title"
app:layout_constraintStart_toEndOf="#id/playlist_song_credit_separator"/>
</android.support.constraint.ConstraintLayout>
<ImageButton
android:id="#+id/playlist_play_button"
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="0dp"
android:layout_gravity="center_vertical"
android:background="#00FFFFFF"
android:src="#drawable/ic_play_arrow_black_24dp"
android:scaleType="centerCrop"/>
</LinearLayout>
Use a variable to store current playing items index
SongAdapter {
int playingIndex = -1 //-1 means no song is playing
.
.
.
}
Set play/pause drawable based on playingIndex and set the playingIndex in the songPlayButton.setOnClickListener
public View getView(final int position, ...) {
if(playingIndex == position)
songPlayButton.setImageResource(R.drawable.ic_play_black_24dp);
else
songPlayButton.setImageResource(R.drawable.ic_pause_black_24dp);
songPlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(position == playIndex)
playIndex = -1;
else
playIndex = position;
notifyDataSetChanged();
}
});
}
It should get the job done. But it forces a redraw of all rows. In RecyclerView there is the notifyItemChanged method which can force redraw on single item.
You may try using the method here to update single row https://stackoverflow.com/a/3727813/4907678
My suggestion is migrating to RecyclerView and using notifyItemChanged.
cheers!
In my app, I send a volley request which fetches list items one-by-one, not all at once. I want to implement a progressbar at the end of the recyclerview when the data is being fetched. The class 'updateAdapter' updates the adapter and I was thinking of making the progress bar visible in the recyclerview scroll listener. But I have no idea how to do this in my code.
updateAdapter.java
//THIS CLASS UPDATES THE RECYCLER VIEW
public class updateAdapter{
private FetchWpApi fetch;
private int totalItemCount;
private int prevLastvisible=0;
private int fpage=1;
private Context context;
private RecyclerView recyclerView;
private ArrayList<sItem> list= new ArrayList<>();
private LinearLayoutManager manager;
private ProgressBar progressBar;
//CONSTRUCTOR FOR updateAdapter
public updateAdapter(RecyclerView recyclerView, final Context context, String url, LinearLayoutManager manager){
this.context=context;
this.recyclerView=recyclerView;
fetch=new FetchWpApi(url,context);
this.manager=manager;
}
public void fetchAndPut()
{
if(recyclerView.getAdapter()==null) {
fetch.fetchApiData(fpage, new FetchWpApi.Callback() {
#Override
public void onSuccess(sItem sitem) {
list.add(sitem);
if (list.size() == 1 || recyclerView.getAdapter() == null) {
ItemAdapter adapter = new ItemAdapter(context, list);
recyclerView.setAdapter(adapter);
} else if (list.size() > 1 && recyclerView.getAdapter() != null) {
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.getAdapter().notifyItemRangeChanged(0, recyclerView.getAdapter().getItemCount());
}
}
#Override
public void onFail(String msg) {
Toast.makeText(context, "FAILED PRIMARY LOAD", Toast.LENGTH_LONG).show();
}
});
}
recyclerView.addOnItemTouchListener(
//Not important
);
//SCROLL LISTENER ATTACHED TO THE RECYCLER VIEW
//SHOW PROGRESS BAR HERE?
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
#Override
public void onScrolled(final RecyclerView recyclerView, int dx, int dy)
{
if(dy > 0) //check for scroll down
{
totalItemCount = manager.getItemCount();
int lastVisibleItemPosition = ((LinearLayoutManager) manager).findLastVisibleItemPosition();
if( (lastVisibleItemPosition+1)==totalItemCount && totalItemCount%10==0 && lastVisibleItemPosition>prevLastvisible)
{
//SET VISIBILITY OF THE PROGRESS BAR IN THE LAST CARD ITEM TO VISIBLE ??
fpage++;
//loading = false;
Log.v("...", "Last Item !");
//Do pagination.. i.e. fetch new data
prevLastvisible=lastVisibleItemPosition;
fetch.fetchApiData(fpage,new FetchWpApi.Callback(){
#Override
public void onSuccess(sItem sitem){
list.add(sitem);
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.getAdapter().notifyItemRangeChanged(0, recyclerView.getAdapter().getItemCount());
}
#Override
public void onFail(String msg){
Toast.makeText(context,"FAILED ONLOAD",Toast.LENGTH_LONG).show();
}
});
}
}
}
});
}
}
The progressbar which I want to display is in this cardview:
finalcard.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cvItem"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!--<LinearLayout-->
<!--android:id="#+id/linearlayout"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_margin="10dp"-->
<!-->-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/tvTitle"
android:textColor="#000"
android:text="Sample text Sampletext sample text sample text sample text"
android:layout_alignParentStart="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="#+id/ivMainImage"
android:layout_marginTop="15dp"
android:paddingStart="16dp"
android:paddingEnd="2dp"
android:maxLines="4"
android:textSize="20sp"
android:layout_gravity="start"
/>
<TextView
android:id="#+id/dateText"
android:text="DATE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="0dp"
android:layout_gravity="start"
android:layout_below="#id/tvTitle"
android:ellipsize="marquee"/>
<ImageView
android:id="#+id/ivMainImage"
android:layout_width="140dp"
android:layout_height="130dp"
android:layout_gravity="end"
android:layout_alignParentEnd="true"
android:layout_margin="15dp"
android:src="#android:drawable/btn_star"
android:scaleType="centerCrop"
/>
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#0C000000"
android:layout_below="#id/ivMainImage"
/>
<ProgressBar
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar2"
android:layout_below="#id/view"
android:visibility="gone"
/>
</RelativeLayout>
Fix your progress bar below your recycler view instead of card view.
Set visible progress bar when call web service, and set visibility Gone after complete service call
//Progress bar setVisibility - Visible
progressbar.setVisibility(View.VISIBLE);
fetch.fetchApiData(fpage, new FetchWpApi.Callback() {
#Override
public void onSuccess(sItem sitem) {
progressbar.setVisibility(View.GONE);
list.add(sitem);
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.getAdapter().notifyItemRangeChanged(0, recyclerView.getAdapter().getItemCount());
}
#Override
public void onFail(String msg) {
progressbar.setVisibility(View.GONE);
Toast.makeText(context, "FAILED ONLOAD", Toast.LENGTH_LONG).show();
}
});
I think you can follow this link to add header or footer Recyclerview offically. And you add footer as progressbar to load more data, and remove footer when you finish loading data.
There are 2 ways:
1. Put the progress bar in the bottom of the screen and when you are bottom of the RecyclerView by int last = layoutManager.findLastVisibleItemPosition(); it just display and when you get the response then hide it;
2. In your adapter:
add a dummy row to the last position of your list.
check in adapter when the position is last then show the progress bar:
if(position == list.size - 1) {
// create a layout which only have progress bar
View row = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.progressbar, viewGroup, false);
} else {
View row = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.layout_list, viewGroup, false);
}
Hello its been 2 days i am searching for a solution for this and still have no idea how to do, i want make a swipe left and right also rearrange recycle view,When user swipe left it will automatically list in completed list and if swipe on left it will delete list item in recycle view also user can rearrange the list element my long press.
Here is main activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView shoppingItems;
private Toolbar toolbar;
private Realm realm;
private CoordinatorLayout coordinatorLayout;
private List<ShoppingItem> dataSet;
private RecyclerView.Adapter shoppingItemsAdapter = new RecyclerView.Adapter() {
private final int ACTIVE_VIEW=1;
private final int INACTIVE_VIEW=2;
private final int SUBHEADER_VIEW=3;
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == ACTIVE_VIEW) {
View v = getLayoutInflater().inflate(R.layout.active_item, parent, false);
return new ActiveItemViewHolder(v,
(CheckBox)v.findViewById(R.id.item_status),
(TextView)v.findViewById(R.id.item_name),
(TextView)v.findViewById(R.id.item_quantity),
(ImageView)v.findViewById(R.id.item_action)
);
} else if(viewType == INACTIVE_VIEW) {
View v = getLayoutInflater().inflate(R.layout.inactive_item, parent, false);
return new InactiveItemViewHolder(v,
(CheckBox)v.findViewById(R.id.item_status),
(TextView)v.findViewById(R.id.item_name),
(ImageView)v.findViewById(R.id.item_action)
);
} else {
View v = getLayoutInflater().inflate(R.layout.subheader, parent, false);
return new SubheaderViewHolder(v);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final ShoppingItem currentItem = dataSet.get(position);
if(currentItem.getTimestamp()==-1) return;
if(currentItem.isCompleted()) {
InactiveItemViewHolder h = (InactiveItemViewHolder)holder;
h.itemName.setText(currentItem.getName());
h.itemName.setPaintFlags(h.itemName.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
h.itemAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "Task is restored", Snackbar.LENGTH_LONG);
snackbar.show();
realm.beginTransaction();
currentItem.setCompleted(false);
currentItem.setTimestamp(System.currentTimeMillis());
realm.commitTransaction();
initializeDataSet();
shoppingItemsAdapter.notifyDataSetChanged();
}
});
}else{
ActiveItemViewHolder h = (ActiveItemViewHolder)holder;
h.itemName.setText(currentItem.getName());
h.itemQuantity.setText(currentItem.getQuantity());
h.itemStatus.setChecked(false);
h.itemStatus.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
if (checked) {
realm.beginTransaction();
currentItem.setCompleted(true);
currentItem.setTimestamp(System.currentTimeMillis());
realm.commitTransaction();
initializeDataSet();
shoppingItemsAdapter.notifyDataSetChanged();
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "Task is Completed", Snackbar.LENGTH_LONG)
.setAction("UNDO", new View.OnClickListener() {
#Override
public void onClick(View view) {
realm.beginTransaction();
currentItem.setCompleted(false);
currentItem.setTimestamp(System.currentTimeMillis());
realm.commitTransaction();
initializeDataSet();
shoppingItemsAdapter.notifyDataSetChanged();
Snackbar snackbar1 = Snackbar.make(coordinatorLayout, "Task is restored!", Snackbar.LENGTH_SHORT);
snackbar1.show();
}
});
snackbar.show();
}
}
});
h.itemAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, ItemActivity.class);
i.putExtra("TITLE", "Edit item");
i.putExtra("ITEM_NAME", currentItem.getName());
i.putExtra("ITEM_QUANTITY", currentItem.getQuantity());
i.putExtra("ITEM_ID", currentItem.getId());
startActivityForResult(i, 1);
}
});
}
}
#Override
public int getItemCount() {
return dataSet.size();
}
#Override
public int getItemViewType(int position) {
ShoppingItem currentItem = dataSet.get(position);
if(currentItem.getTimestamp()==-1) return SUBHEADER_VIEW;
if(currentItem.isCompleted()) return INACTIVE_VIEW;
return ACTIVE_VIEW;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
RealmConfiguration configuration =
new RealmConfiguration.Builder(this).build();
Realm.setDefaultConfiguration(configuration);
realm = Realm.getDefaultInstance();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, ItemActivity.class);
i.putExtra("TITLE", "Add Task");
startActivityForResult(i, 1);
}
});
shoppingItems = (RecyclerView)findViewById(R.id.shopping_items);
shoppingItems.setLayoutManager(new LinearLayoutManager(this));
initializeDataSet();
shoppingItems.setAdapter(shoppingItemsAdapter);
}
private void initializeDataSet() {
dataSet = new ArrayList<>();
RealmResults<ShoppingItem> activeItemResults
= realm.where(ShoppingItem.class).equalTo("completed", false)
.findAllSorted("timestamp", Sort.DESCENDING);
RealmResults<ShoppingItem> inactiveItemResults
= realm.where(ShoppingItem.class).equalTo("completed", true)
.findAllSorted("timestamp", Sort.DESCENDING);
ShoppingItem subheader = new ShoppingItem();
subheader.setTimestamp(-1);
for(ShoppingItem item:activeItemResults) dataSet.add(item);
dataSet.add(subheader);
for(ShoppingItem item:inactiveItemResults) dataSet.add(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
initializeDataSet();
shoppingItemsAdapter.notifyDataSetChanged();
}
}
activity main.xml
android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.github.hathibelagal.shoppinglist.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_add_24dp"
android:tint="#android:color/white" />
</android.support.design.widget.CoordinatorLayout>
active_item.xml:
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="72dp">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/item_status"
android:layout_centerVertical="true"
android:layout_alignParentStart="true" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="72dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/item_name"
android:textColor="#android:color/black" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/item_quantity" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/item_action"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:src="#drawable/ic_create_24dp"
android:alpha="0.26" />
</RelativeLayout>
Please help me! Thanks for advance!
Try this out :
https://medium.com/#ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.lrbbupqkq
Stack Overflow post for the same :
RecyclerView Swipe with a view below it
Drag and drop items in RecyclerView with GridLayoutManager