I'm trying to use a Searchview with Recylerview and firebase database, i've been following some tutorial and i've followed the video correctly so I don't know why i'm getting an error,i have three classn one is an adapater and a helper and the main one, the error i get is:
2021-05-12 03:16:12.931 31658-31658/com.example.search E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.search, PID: 31658
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.search.Deal
in the following line:
list.add(ds.getValue(Deal.class));
this is my main activity:
package com.example.search;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Deal> list;
RecyclerView recyclerView;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ref = FirebaseDatabase.getInstance().getReference().child("medicines");
recyclerView = findViewById(R.id.rv);
searchView = findViewById(R.id.searchview);
}
#Override
protected void onStart() {
super.onStart();
if(ref != null){
ref.addValueEventListener(new ValueEventListener() {
#NonNull
#Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
for(DataSnapshot ds : snapshot.getChildren()){
list.add(ds.getValue(Deal.class));
}
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
if (searchView != null){
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
}
private void search(String str) {
if (!str.equals("")){
ArrayList<Deal>myList = new ArrayList<>();
for (Deal object : list){
if(object.getDisease().toLowerCase().contains(str.toLowerCase())){
myList.add(object);
}
}
AdapterClass adapterClass = new AdapterClass(myList);
recyclerView.setAdapter(adapterClass);
}
}
}
and this is my "helper" class which i called deal:
package com.example.search;
public class Deal {
private String disease, medication;
public Deal() {
}
public Deal(String disease, String medication) {
this.disease = disease;
this.medication = medication;
}
public String getDisease() {
return disease;
}
public void setDisease(String disease) {
this.disease = disease;
}
public String getMedication() {
return medication;
}
public void setMedication(String medication) {
this.medication = medication;
}
}
this is my adapater class:
package com.example.search;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.MyViewHolder> {
ArrayList<Deal> list;
public AdapterClass(ArrayList<Deal> list){
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_holder, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.disease.setText(list.get(position).getDisease());
holder.medicine.setText(list.get(position).getMedication());
}
#Override
public int getItemCount() {
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView disease, medicine;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
disease = itemView.findViewById(R.id.disease);
medicine = itemView.findViewById(R.id.medication);
}
}
}
and this is my main activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="#+id/searchview"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:padding="10dp"
android:layout_margin="5dp"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:autofillHints="Search here"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
</LinearLayout>
and my card view layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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:layout_margin="5dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="#+id/disease"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textStyle="bold"
android:padding="10dp"
android:text="disease_name" />
<TextView
android:id="#+id/medication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="solution"
android:padding="10dp"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"
/>
</androidx.cardview.widget.CardView>
that's all there is to the whole app so i dont get why the app keeps crashing, this is what my firebase database looks like
{
"medicines" : {
"disease" : "maleria",
"medication" : "aspirin"
}
}
I was getting different exceptions before and I changed the rules in database and debugged the app and now I'm getting this error been stuck on it for two hours, Honestly no clue, I've already tried checking if I wrote things wrong and if the names I added in my helper(deal)class match with the ones in firebase etc., and they do so I don't know
Since your Deal class defines properties disease and mediation, there seems to be only one Deal object under medicines.
So with your current data, you shouldn't be using a loop over getChildren in the onDataChange, and simple do:
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
list.add(snapshot.getValue(Deal.class));
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
Related
I am working with Retrofit. I followed a tutorial and did exactly what he said. Response is working perfectly in a single TextView but not in RecyclerView. When I added an adapter class, it start crashing. I read logcat file too but didn't seem helpful. The app crashes without showing any error or exception.
Here is my main XML class with a RecyclerView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<!-- <ScrollView-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent">-->
<!-- <TextView-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:id="#+id/text1"-->
<!-- android:layout_marginTop="5dp"-->
<!-- android:layout_marginStart="2dp">-->
<!-- </TextView>-->
<!-- </ScrollView>-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
My main class is working fine with a for loop to print data in one TextView but not for adapter or RecyclerView.
package com.example.apipractice;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class MainActivity extends AppCompatActivity {
apiInterface instanceforAPI;
LinearLayoutManager linearLayoutManager;
//TextView txt;
RecyclerView recview;
adapter ad;
List<jsonData> data = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//txt = findViewById(R.id.text1);
recview = findViewById(R.id.recview);
linearLayoutManager = new LinearLayoutManager(this);
recview.setLayoutManager(linearLayoutManager);
instanceforAPI = retrofitInstance.getRetrofit().create(apiInterface.class);
instanceforAPI.getdata().enqueue(new Callback<List<jsonData>>() {
#Override
public void onResponse(Call<List<jsonData>> call, Response<List<jsonData>> response) {
if(response.body().size()>0){
Toast.makeText(MainActivity.this,"yayy",Toast.LENGTH_LONG).show();
data.addAll(response.body());
ad = new adapter(data);
ad.notifyDataSetChanged();
recview.setAdapter(ad);
// for (int index=0;index<data.size();index++){
// txt.setText(txt.getText()+ " SRNo.: "+data.get(index).getTitle()+" \n" + data.size());
//
// }
}
else
{
Toast.makeText(MainActivity.this,"No yayy",Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<List<jsonData>> call, Throwable t) {
Toast.makeText(MainActivity.this,t.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
SingleRow design XML class (single.xml) is as follows:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:rotationX="8">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
></TextView>
<TextView
android:id="#+id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="title"
></TextView>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Adapter class (adapter.java) for fetching data is as follows:
package com.example.apipractice;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class adapter extends RecyclerView.Adapter<adapter.myviewholder> {
List<jsonData> data;
public adapter(List<jsonData> data){
this.data = data;
}
#Override
public myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single,parent,false );
return new myviewholder(v);
}
#Override
public void onBindViewHolder(#NonNull adapter.myviewholder holder, int position) {
holder.t1.setText((int) data.get(position).getId());
holder.t2.setText( data.get(position).getTitle());
}
#Override
public int getItemCount() {
return data.size();
}
public class myviewholder extends RecyclerView.ViewHolder
{
TextView t1,t2;
public myviewholder(#NonNull View itemView) {
super(itemView);
t1= itemView.findViewById(R.id.t1);
t2 = itemView.findViewById(R.id.t2);
}
}
}
The following class is for retrofit instance, retrofitInstance.java:
package com.example.apipractice;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class retrofitInstance {
private static Retrofit retrofit;
private static final String commonURL = "https://jsonplaceholder.typicode.com";
public static Retrofit getRetrofit() {
if(retrofit ==null) {
retrofit = new Retrofit.Builder().baseUrl(commonURL).addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
}
This interface class (apiInterfce.java) is for the API get call:
package com.example.apipractice;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
public interface apiInterface {
#GET("/posts?type=json")
Call<List<jsonData>> getdata();
}
My model class, jsonData.java:
package com.example.apipractice;
public class jsonData {
private float userId;
private float id;
private String title;
private String body;
// Getter Methods
public float getUserId() {
return userId;
}
public float getId() {
return id;
}
public String getTitle() {
return title;
}
public String getBody() {
return body;
}
// Setter Methods
public void setUserId(float userId) {
this.userId = userId;
}
public void setId(float id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setBody(String body) {
this.body = body;
}
}
Don't pass int value in setText() method. Because it consider int value as a resource id.
Please do as follow:
#Override
public void onBindViewHolder(#NonNull adapter.myviewholder holder, int position) {
holder.t1.setText(data.get(position).getId() + "");
holder.t2.setText( data.get(position).getTitle());
}
I am unable to display the image (only) in RecyclerView stored in Firebase Storage, while I'm displaying the other text data in the recyclerView.
I browse through a lot of questions but i didn't find the answer for me .
hint: all roles for Realtime Database , Firebase Storage is set either to [true or test mode]
hint : below is the link for out put image :
https://i.stack.imgur.com/dagbA.jpg
data model
import com.google.firebase.database.Exclude;
public class House {
#Exclude
private String key;
//owner name
private String name ;
//location
private String Location;
//image
private String imageUrl;
/*all start with [RealState] (realTimeDatabase/storage)*/
/*
* [RealStateData] - database
* [RealStatePictures] - storage
* */
public House() {
//required
}
public House(String name, String location, String imageUrl) {
if (name.trim().equals("") || name.isEmpty()){
name = "realState company";
}
this.name = name;
Location = location;
this.imageUrl = imageUrl;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return Location;
}
public void setLocation(String location) {
Location = location;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
#Exclude
public String getKey() {
return key;
}
#Exclude
public void setKey(String key) {
this.key = key;
}
}
Adapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.squareup.picasso.Picasso;
import com.techmarinar.royalhomes.data.House;
import java.util.List;
public class HouseAdapter extends RecyclerView.Adapter<HouseAdapter.HouseHolder> {
private static final String TAG = "HouseAdapter";
private Context mContext;
private List<House> houseList;
public HouseAdapter(Context mContext, List<House> houseList) {
this.mContext = mContext;
this.houseList = houseList;
}
public void setUploads(List<House> uploads) {
this.houseList = uploads;
this.notifyDataSetChanged();
}
#NonNull
#Override
public HouseHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v= LayoutInflater.from(mContext)
.inflate(R.layout.list_item,parent,false);
return new HouseHolder(v);
}
#Override
public void onBindViewHolder(#NonNull HouseHolder holder, int position) {
//house object
House house = houseList.get(position);
holder.name.setText(house.getName());
holder.location.setText(house.getLocation());
// holder.image.setImageURI(Uri .parse(house.getImageUrl());
String imageUrl = house.getImageUrl();
Glide.with(mContext)
.load(imageUrl)
.placeholder(R.drawable.ic_baseline_add_business_24)
.centerCrop()
.into(holder.image);
}
#Override
public int getItemCount() {
return houseList.size();
}
#Override
public long getItemId(int position) {
return position;
}
public class HouseHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView name;
private TextView location ;
public HouseHolder(#NonNull View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.xHouseImage);
name = (TextView) itemView.findViewById(R.id.xHouseName);
location = (TextView) itemView.findViewById(R.id.xHouseLocation);
}
}
}
MainActicity -- recyclerclass
package com.techmarinar.royalhomes;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.techmarinar.royalhomes.data.House;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
private static final String TAG = "MainActivity";
//widget
private RecyclerView mRecycler;
private ProgressBar mProgress;
//firebase Element
private StorageReference storageReference;
private DatabaseReference databaseReference;
//Adapters var
private List<House> houseList;
private HouseAdapter mAdapter;
private ValueEventListener getFirebaseData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set Widget
setupUIWidget();
//init firebase
initiateFireBaseElement();
//set recyclerView
setupRecyclerView();
//get data from fire(storage/fireDataBase);
getHousesDataFromFireBase();
//setup Item Touch Helper
setupItemTouchHelper(mRecycler , mAdapter);
}
private void setupUIWidget() {
setTitle("home");
//widget
mProgress = (ProgressBar) findViewById(R.id.progress_circular);
mRecycler = (RecyclerView) findViewById(R.id.recycler);
FloatingActionButton mActionButton = (FloatingActionButton) findViewById(R.id.floatingBtn);
//ActionButton
mActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Toast.makeText(MainActivity.this, "wow", Toast.LENGTH_SHORT).show();
startActivity(new Intent(MainActivity.this , EditHouse.class));
}
});
}
private void initiateFireBaseElement() {
//fireBase reference
databaseReference = FirebaseDatabase.getInstance().getReference("RealStateData");
storageReference= FirebaseStorage.getInstance().getReference("RealStatePictures") ;
}
private void setupRecyclerView() {
Log.d(TAG, "setupRecyclerView: ");
houseList = new ArrayList<>();
mRecycler.setLayoutManager(new LinearLayoutManager(this));
mRecycler.setHasFixedSize(true);
//mRecycler.setHasStableIds(true);
//init adapter
mAdapter = new HouseAdapter(MainActivity.this,houseList);
//set adapter to the recyclerView
mRecycler.setAdapter(mAdapter);
}
private void getHousesDataFromFireBase() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
houseList.clear();
for (DataSnapshot data : snapshot.getChildren()) {
//init house object
House houseValues = data.getValue(House.class);
// houseValues.setKey(data.getKey());
//fill the list
houseList.add(houseValues);
}
//notify the adapter
mAdapter.setUploads(houseList);
//mAdapter.notifyDataSetChanged();
//hide the progressBar
mProgress.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.d(TAG, "onCancelled: " + error.getMessage());
Toast.makeText(MainActivity.this, "" + error.getMessage(), Toast.LENGTH_SHORT).show();
//hide progressbar
mProgress.setVisibility(View.INVISIBLE);
}
});
}
private void setupItemTouchHelper(RecyclerView mRecycler, HouseAdapter mAdapter) {
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
}).attachToRecyclerView(mRecycler);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//menu
MenuItem addNewHouse , deleteHouse , updateHouse;
addNewHouse= menu.add(0,1,1,"add house");
addNewHouse.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
addNewHouse.setIcon(R.drawable.ic_baseline_supervised_user_circle_24);
updateHouse= menu.add(0,2,2,"update house");
deleteHouse= menu.add(0,3,3,"delete house");
addNewHouse.setOnMenuItemClickListener(this);
updateHouse.setOnMenuItemClickListener(this);
deleteHouse.setOnMenuItemClickListener(this);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case 1:
Toast.makeText(this, "new house", Toast.LENGTH_SHORT).show();
return true;
case 2:
Toast.makeText(this, "update house data", Toast.LENGTH_SHORT).show();
return true;
case 3:
Toast.makeText(this, "delete house data", Toast.LENGTH_SHORT).show();
return true;
default:return false;
}
}
}
here is xml files
List item:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
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:layout_margin="2dp"
app:cardBackgroundColor="#color/purple_200"
app:cardElevation="12dp"
app:cardCornerRadius="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="8dp">
<!--this view is only for beautiful looks -->
<View
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#color/purple_200"/>
<!--this view is only for beautiful looks -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/white"/>
<ImageView
android:id="#+id/xHouseImage"
android:layout_width="match_parent"
android:layout_height="220dp"
android:adjustViewBounds="true" />
<!--this view is only for beautiful looks -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/white"/>
<TextView
android:id="#+id/xHouseLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="house Location"
android:layout_margin="4dp"
android:layout_marginStart="6dp"
android:fontFamily="sans-serif-light"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textStyle="bold"
android:textColor="#color/black"
android:textSize="33sp"/>
<TextView
android:id="#+id/xHouseName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="house owner name"
android:layout_margin="4dp"
android:layout_marginStart="8dp"
android:fontFamily="sans-serif-light"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textColor="#color/black"
android:textSize="16sp"
android:gravity="top|center_vertical" />
</LinearLayout>
</androidx.cardview.widget.CardView>
recycler
<?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"
android:layout_margin="8dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_goneMarginBottom="8dp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
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.029" />
<ProgressBar
android:id="#+id/progress_circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.446"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.406" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_baseline_home_work_24"
android:backgroundTint="#color/white"
android:foregroundGravity="bottom|right"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.905"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.945" />
</androidx.constraintlayout.widget.ConstraintLayout>
Try this applyDefaultRequestOptions Method for Center crop of the image
Glide.with(mContext)
.applyDefaultRequestOptions(RequestOptions().centerCrop())
.load(imageUrl)
.placeholder(R.drawable.ic_baseline_add_business_24)
.into(target!!)
the problem was in Manifest.xml security issuess.
solution :
adding
android:usesCleartextTraffic="true"
to the application section
I am trying to fetch database from firebase but i cant get any text in cardview. Below is the xml file of card view.
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/colorAccent"
>
<TextView
android:id="#+id/viewname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Name"
android:textColor="#F44336"
android:textSize="132dp" />
<TextView
android:id="#+id/viewgenere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Genre"
android:textSize="32sp" />
</LinearLayout>
Below is the activity file
<?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=".ViewUser">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerview"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Below is the activity file
package com.example.firebasedatabase;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.view.ViewGroup;
import com.example.firebasedatabase.Adapter.UserAdapter;
import com.example.firebasedatabase.Model.Showuser;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class ViewUser extends AppCompatActivity {
private RecyclerView recyclerView;
private DatabaseReference userdatabase;
UserAdapter userAdapter;
private List<Showuser>listData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_user);
recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
listData=new ArrayList<>();
userdatabase= FirebaseDatabase.getInstance().getReference("users");
userdatabase.keepSynced(true);
userdatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
for (DataSnapshot npsnapshot : dataSnapshot.getChildren()){
Showuser showuser=npsnapshot.getValue(Showuser.class);
listData.add(showuser);
}
userAdapter=new UserAdapter(listData);
recyclerView.setAdapter(userAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Below is the recycleradapter
package com.example.firebasedatabase.Adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.firebasedatabase.Model.Showuser;
import com.example.firebasedatabase.R;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import java.util.List;
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder>{
Context context;
private List<Showuser>listData;
public UserAdapter(Context context,List<Showuser>listData)
{
this.context=context;
this.listData=listData;
}
public UserAdapter(List<Showuser> listData) {
}
//
//
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.usercard,parent,false);
// return new ViewHolder(view) {
//
// };
return new ViewHolder(LayoutInflater.from(context)
.inflate(R.layout.usercard,parent,false));
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.txtuser.setText(new StringBuilder(listData.get(position).getShowuserName()));
holder.txtgenre.setText(new StringBuilder(listData.get(position).getShowuserGenre()));
}
#Override
public int getItemCount() {
return listData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView txtuser,txtgenre;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txtuser=(TextView)itemView.findViewById(R.id.viewname);
txtgenre=(TextView)itemView.findViewById(R.id.viewgenere);
}
}
}
I cannot view any text coming from firebase database.The firebase database rules are true.The view is created; just as i enter 4 data in firebase then it shows 4 card view but no text is shown and there is space between 1 card & 2 card near about 4 blank rows.
please help me out
I see the issue.
userAdapter=new UserAdapter(listData);
recyclerView.setAdapter(userAdapter);
Here you are initializing your UserAdapter. Notice that you are calling the wrong constructor or perhaps you have not implemented it.
// You should call this instead
public UserAdapter(Context context,List<Showuser>listData)
{
this.context=context;
this.listData=listData;
}
// You are calling this empty constructor
public UserAdapter(List<Showuser> listData) {
}
You should initialize your adapter like below.
userAdapter=new UserAdapter(ViewUser.this, listData);
You miss setting the list in adapter constructor, so change below
public UserAdapter(List<Showuser> listData) {
}
With
public UserAdapter(List<Showuser> listData) {
this.listData=listData;
}
Also, the list might be null, so change the return value of getItemCount()
#Override
public int getItemCount() {
return listData.size();
}
with
#Override
public int getItemCount() {
return listData == null? 0: listData.size();
}
So I have a Firebase database as follows:
I have a recycler view list with job names. When the person clicks on an item, it has to expand to show more information about it. In order to do that I believe I have to retrieve the data based on the main children keys like Job1, Job2 etc. How would I do this? I have tried to look up on similar questions but I can't help feeling a bit lost since I'm only a beginner. I'd appreciate it if someone answered this with simple explanations to help me learn.
This is my main Home class:
package com.example.oddsynew;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class Home extends AppCompatActivity {
DatabaseReference myRef;
RecyclerView newJobList;
ArrayList<Job> list;
HomeAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
newJobList = (RecyclerView) findViewById(R.id.newJobs);
newJobList.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<Job>();
adapter = new HomeAdapter(Home.this, list);
newJobList.setAdapter(adapter);
myRef = FirebaseDatabase.getInstance().getReference().child("Jobs");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String jobkey = ds.getKey();
Job j = ds.getValue(Job.class);
list.add(j);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(Home.this, "Error", Toast.LENGTH_SHORT).show();
}
});
}
}
Followed by my adapter class:
package com.example.oddsynew;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {
Context context;
ArrayList<Job> jobs;
public HomeAdapter(Context c, ArrayList<Job> j){
context = c;
jobs = j;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.job_row, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, final int position) {
holder.recruiterName.setText(jobs.get(position).getRecruiter_name());
holder.jobName.setText(jobs.get(position).getJob_name());
holder.jobLocation.setText(jobs.get(position).getLocation());
holder.jobCharge.setText(jobs.get(position).getJob_charge());
Picasso.get().load(jobs.get(position).getProf_pic()).into(holder.profPic);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String recruiter_id; //I'm not sure what to do here.
}
});
}
#Override
public int getItemCount() {
return jobs.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView recruiterName, jobName, jobLocation, jobCharge;
ImageView profPic;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
recruiterName = itemView.findViewById(R.id.recruiterName);
jobName = itemView.findViewById(R.id.jobName);
jobLocation = itemView.findViewById(R.id.jobLocation);
jobCharge = itemView.findViewById(R.id.jobCharge);
profPic = itemView.findViewById(R.id.prof_pic);
}
}
}
And here is my model:
package com.example.oddsynew;
public class Job {
private String job_name;
private String recruiter_name;
private String location;
private String job_charge;
private String prof_pic;
public Job() {
}
public Job(String job_name, String recruiter_name, String location, String job_charge, String prof_pic) {
this.job_name = job_name;
this.recruiter_name = recruiter_name;
this.location = location;
this.job_charge = job_charge;
this.prof_pic = prof_pic;
}
public Job(String prof_pic) {
this.prof_pic = prof_pic;
}
public String getJob_name() {
return job_name;
}
public void setJob_name(String job_name) {
this.job_name = job_name;
}
public String getRecruiter_name() {
return recruiter_name;
}
public void setRecruiter_name(String recruiter_name) {
this.recruiter_name = recruiter_name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getJob_charge() {
return job_charge;
}
public void setJob_charge(String job_charge) {
this.job_charge = job_charge;
}
public String getProf_pic() {
return prof_pic;
}
public void setProf_pic(String prof_pic) {
this.prof_pic = prof_pic;
}
}
My Recycler View UI
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="14dp"
android:layout_marginRight="14dp"
android:elevation="90dp"
android:orientation="vertical"
app:cardCornerRadius="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#fff"
android:orientation="vertical">
<ImageView
android:id="#+id/prof_pic"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="12dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
<TextView
android:id="#+id/recruiterName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="16dp"
android:fontFamily="#font/roboto"
android:textColor="#000"
android:textSize="14sp"
android:textStyle="normal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#+id/prof_pic"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/jobName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:fontFamily="#font/roboto_bold"
android:textColor="#000"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/prof_pic"
app:layout_constraintTop_toBottomOf="#+id/recruiterName" />
<TextView
android:id="#+id/jobLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="24dp"
android:fontFamily="#font/roboto_light"
android:textColor="#000"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/prof_pic"
app:layout_constraintTop_toBottomOf="#+id/jobName"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/jobCharge"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:fontFamily="#font/roboto_light"
android:textColor="#000"
android:textSize="12sp"
app:layout_constraintBaseline_toBaselineOf="#+id/jobLocation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/jobLocation" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
EDIT: This is my recycler list view. I have retrived data from firebase and displayed it on the items. The first list item is info from Job1. When I click on the first item, it should go to another page lets call it "jobInfo" to display more information about that particular job. What I'm struggling with is how do I make sure information only about job1 is displayed when I click the first item. Sorry if I wasn't clear before.
In home activity:
myRef = FirebaseDatabase.getInstance().getReference().child("Jobs");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String jobkey = ds.getKey();
Job j = ds.getValue(Job.class);
list.add(j);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(Home.this, "Error", Toast.LENGTH_SHORT).show();
}
});
In Job model class implement Serializable
public class Job implements Serializable
In adapter click listener
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, jobInfo.class);
intent.putExtra("yourKey",jobs.get(position));
startActivity(intent);
}
});
In jobInfo activity
Job job = (Job) getIntent().getSerializableExtra("yourKey");
in job you will get all values
I was able to make it work with this code in my job info class:
package com.example.oddsynew;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.squareup.picasso.Picasso;
public class JobInfo extends AppCompatActivity {
TextView jobName, jobCharge, jobLocation;
ImageView profPic;
String jobname, jobloc, jobcharge, profpic;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_job_info);
jobName = (TextView) findViewById(R.id.jobName_info);
jobCharge = (TextView) findViewById(R.id.jobCharge_info);
jobLocation = (TextView) findViewById(R.id.jobLocation_info);
profPic = (ImageView) findViewById(R.id.prof_pic_info);
jobname = getIntent().getStringExtra("jobName");
jobloc = getIntent().getStringExtra("jobLocation");
jobcharge = getIntent().getStringExtra("jobCharge");
profpic = getIntent().getStringExtra("profPic");
jobName.setText(jobname);
jobCharge.setText(jobcharge);
jobLocation.setText(jobloc);
Picasso.get().load(profpic).into(profPic);
}
}
And adding this under setOnClickListener in my adapter class:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, JobInfo.class);
intent.putExtra("recruiterName",jobs.get(position).getRecruiter_name());
intent.putExtra("jobName",jobs.get(position).getJob_name());
intent.putExtra("jobCharge",jobs.get(position).getJob_charge());
intent.putExtra("jobLocation",jobs.get(position).getLocation());
intent.putExtra("profPic",jobs.get(position).getProf_pic());
context.startActivity(intent);
}
});
}
I'm new with android firebase. My problem is that I would like to display the list of my data in the database in a
recycleview. I have a tablayout that contains 3 tabs. it's in the first tab that I want to display my data, I use a fragment
in which I met my recycleview, i also the method
Blockquote
addValueEventListener
Blockquote
to take my firebase data. Whenever I launch the application it displays nothing I have this message
Blockquote
E / RecyclerView: No adapter attached; skip the layout
Blockquote
.Is this someone can help me. Thanks in Advance
My Firebase Data[1]: https://imgur.com/gallery/uIOEPuA
HomeActivity.java
package com.example.saincurin.htfacile;
import android.os.Build;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabItem;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.saincurin.htfacile.Adapters.PageAdapter;
public class HomeActivity extends AppCompatActivity {
private Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
private DrawerLayout mDrawer;
private NavigationView nvDrawer;
private ActionBarDrawerToggle drawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
toolbar = findViewById(R.id.toolbar);
mDrawer = findViewById(R.id.drawer_layout);
nvDrawer = findViewById(R.id.nvView);
tabLayout = findViewById(R.id.tabLayout);
viewPager = findViewById(R.id.viewPager);
toolbar.setTitle(getResources().getString(R.string.app_name));
setSupportActionBar(toolbar);
// Set up Drawer View
PagerAdapter pagerAdapter = new PageAdapter(getSupportFragmentManager(), HomeActivity.this);
viewPager.setAdapter(pagerAdapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(HomeActivity.this,
R.color.colorAccent));
}
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, mDrawer, toolbar,
R.string.drawer_open, R.string.drawer_close);
mDrawer.addDrawerListener(toggle);
toggle.syncState();
// give the Tablayout the viewPager
tabLayout.setupWithViewPager(viewPager);
// setupDrawerContent(nvDrawer);
}
#Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
// private void setupDrawerContent(NavigationView navigationView) {
// navigationView.setNavigationItemSelectedListener(
// new NavigationView.OnNavigationItemSelectedListener() {
// #Override
// public boolean onNavigationItemSelected(MenuItem menuItem) {
// selectDrawerItem(menuItem);
// return true;
// }
// });
// }
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_products, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_more) {
Toast.makeText(this, "The more is selected", Toast.LENGTH_SHORT).show();
}else if (item.getItemId() == R.id.action_search) {
Toast.makeText(this, "The search is selected", Toast.LENGTH_SHORT ).show();
}else if (item.getItemId() == R.id.drawer_layout) {
mDrawer.openDrawer(GravityCompat.START);
}
return true;
}
}
My Model
package com.example.saincurin.htfacile.ModelData;
public class DataModel {
private String description;
private String name;
private String image;
private String price;
private String quantity;
//constructor
public DataModel() {
}
public DataModel(String name, /*String description,*/ String image, String price) {
this.name = name;
// this.description = description;
this.image = image;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getQuantity() {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
My Adapter
package com.example.saincurin.htfacile.Adapters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.saincurin.htfacile.ModelData.DataModel;
import com.example.saincurin.htfacile.R;
import com.squareup.picasso.Picasso;
import java.util.List;
// Create the basic adapter extending from RecyclerView.Adapter
// Note that we specify the custom ViewHolder which gives us access to our views
public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.ProductsviewHolder> {
private Context mcontext;
// Store a member variable for the contacts
private List<DataModel> mDataModel;
public ProductsAdapter(Context context, List<DataModel> mDataModel) {
mcontext = context;
this.mDataModel = mDataModel;
}
// Usually involves inflating a layout from XML and returning the holder
#NonNull
#Override
public ProductsviewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate the custom Layout
View dataView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
//return a new holder instance
return new ProductsviewHolder(dataView);
}
// Involves populating data into the item through holder
#Override
public void onBindViewHolder(#NonNull ProductsviewHolder holder, int position) {
// Get the data model based on position
DataModel dataModel = mDataModel.get(position);
// Set item views based on your views and data model
holder.txtName.setText(dataModel.getName());
// holder.txtDescription.setText(dataModel.getDescription());
holder.txtPrice.setText(dataModel.getPrice());
Picasso.with(mcontext)
.load(dataModel.getImage())
.fit()
.centerCrop()
.into(holder.imageView);
}
#Override
public int getItemCount() {
return mDataModel.size();
}
// Provide a direct reference to each of the views within a data item
// Used to cache the views within the item layout for fast access
public class ProductsviewHolder extends RecyclerView.ViewHolder {
public TextView txtName;
// public TextView txtDescription;
public TextView txtPrice;
public TextView txtQuantity;
public ImageView imageView;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
public ProductsviewHolder(View itemView) {
// Stores the itemView in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(itemView);
txtName = itemView.findViewById(R.id.rvTitleTv);
// txtDescription = itemView.findViewById(R.id.rDescriptionTv);
txtPrice = itemView.findViewById(R.id.rPrice);
imageView = itemView.findViewById(R.id.rImageView);
}
}
}
My first Fragment tab
package com.example.saincurin.htfacile.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.example.saincurin.htfacile.Adapters.ProductsAdapter;
import com.example.saincurin.htfacile.ModelData.DataModel;
import com.example.saincurin.htfacile.R;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
/**
* A simple {#link Fragment} subclass.
*/
public class ProductsFragment extends Fragment {
private RecyclerView mRecycleView;
private ProductsAdapter mProductsAdapter;
private DatabaseReference mReference;
private List<DataModel> mDataModel;
View v;
public ProductsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_products, container, false);
//RecycleView
mRecycleView = v.findViewById(R.id.recycleView);
mRecycleView.setHasFixedSize(true);
//set Layout as LinearLayout
mRecycleView.setLayoutManager(new LinearLayoutManager(getContext()));
mDataModel = new ArrayList<>();
//send Query FirebaseDatabase
mReference = FirebaseDatabase.getInstance().getReference("uploads");
Log.e("DEBUG", "The Reference :"+mReference);
mReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
DataModel dataModel = postSnapshot.getValue(DataModel.class);
mDataModel.add(dataModel);
}
// Log.e("DEBUG","The data model "+ mDataModel.toString());
mProductsAdapter = new ProductsAdapter(getContext(), mDataModel);
// Log.e("DEBUG","The data model "+ mProductsAdapter);
//set the adapter to the recyclerview
mRecycleView.setAdapter(mProductsAdapter);
mProductsAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
return v;
}
}
Layout for my first tab pager
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.ProductsFragment">
<!--RecycleView-->
<android.support.v7.widget.RecyclerView
android:id="#+id/recycleView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Layout for my HomeActivity
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".HomeActivity"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark" />
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar"
style="#style/myCustomTabLayout"
android:background="#color/colorPrimary"
app:tabSelectedTextColor="#android:color/white"
app:tabTextColor="#android:color/black">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nvView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#android:color/white"
app:headerLayout="#layout/nav_header"
app:menu="#menu/drawer_view" />
</android.support.v4.widget.DrawerLayout>
My item_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="#fff"
app:cardCornerRadius="3dp"
app:cardElevation="3dp"
app:cardUseCompatPadding="true"
app:contentPadding="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/rvTitleTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:textColor="#000"
android:textSize="22sp"
android:textStyle="bold" />
<ImageView
android:id="#+id/rImageView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:adjustViewBounds="true"
android:background="#drawable/loading"
android:scaleType="center" />
<TextView
android:id="#+id/rPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="150 gdes"
android:textSize="20dp"
android:textStyle="bold" />
<!--<TextView-->
<!--android:id="#+id/rDescriptionTv"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:text="This is the post description that"-->
<!--android:textSize="20sp" />-->
</LinearLayout>
</android.support.v7.widget.CardView>
Welcome to StackOverflow. The RecyclerView is quite specific when it comes to its setup. So you need to make sure you set up the adapter before setting the layout manager and the fixedSize property.
Try changing your onCreateView method to this:
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_products, container, false);
// Notice that I changed the order of RecyclerView setup
mRecycleView = v.findViewById(R.id.recycleView);
mDataModel = new ArrayList<>();
mProductsAdapter = new ProductsAdapter(getContext(), mDataModel);
mRecyclerView.setAdapter(mProductsAdapter);
mRecycleView.setHasFixedSize(true);
//set Layout as LinearLayout
mRecycleView.setLayoutManager(new LinearLayoutManager(getContext()));
//send Query FirebaseDatabase
mReference = FirebaseDatabase.getInstance().getReference("uploads");
mReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
DataModel dataModel = postSnapshot.getValue(DataModel.class);
mDataModel.add(dataModel);
}
mProductsAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
return v;
}