I'm currently using a method made by Prabeesh R K from YouTube. I'm currently following all the steps without a miss, and I'm only modifying it a little, but the problem is the RecyclerView in my phone is not showing anything. Moreover, there is an error in log : E/RecyclerView: No adapter attached; skipping layout. Can you please help me resolve this. By the way this is my code
GenreView.java (Activity)
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
/**
* Created by A46CB on 2/21/2016.
*/
public class GenreView extends AppCompatActivity{
RecyclerView rvgenre;
GenreAdapter adaptergenre;
RecyclerView.LayoutManager genrelayoutmanager;
String[] judulgenre;
int []imgres = {R.drawable.w06, R.drawable.w100, R.drawable.w102, R.drawable.w144, R.drawable.w173,
R.drawable.w179, R.drawable.w182, R.drawable.w36, R.drawable.w77, R.drawable.w79, R.drawable.w93,
R.drawable.w97};
ArrayList<GenreContent> arrayList = new ArrayList<GenreContent>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_genre);
rvgenre = (RecyclerView)findViewById(R.id.genre_recycler_view);
rvgenre.setHasFixedSize(true);
judulgenre = getResources().getStringArray(R.array.genre_title);
int i = 0;
for(String name : judulgenre)
{
GenreContent genrecontent = new GenreContent(imgres[i],judulgenre[i]);
arrayList.add(genrecontent);
i++;
}
genrelayoutmanager = new GridLayoutManager(this, 2);
rvgenre.setLayoutManager(genrelayoutmanager);
adaptergenre = new GenreAdapter(arrayList);
rvgenre.setAdapter(adaptergenre);
}
}
GenreAdapter.Java (Adapter)
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 java.util.ArrayList;
/**
* Created by A46CB on 2/21/2016.
*/
public class GenreAdapter extends RecyclerView.Adapter<GenreAdapter.GenreRecyclerViewHolder> {
private ArrayList<GenreContent> arrayList = new ArrayList<GenreContent>();
public GenreAdapter(ArrayList<GenreContent> arrayList)
{
this.arrayList = arrayList;
}
#Override
public GenreRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.genre_layout, parent, false);
GenreRecyclerViewHolder grvh = new GenreRecyclerViewHolder(view);
return grvh;
}
#Override
public void onBindViewHolder(GenreRecyclerViewHolder holder, int position) {
GenreContent genreContent = arrayList.get(position);
holder.imgView.setImageResource(genreContent.getImg());
holder.tvgenre.setText(genreContent.getTitle());
}
#Override
public int getItemCount() {
return arrayList.size();
}
public static class GenreRecyclerViewHolder extends RecyclerView.ViewHolder {
ImageView imgView;
TextView tvgenre;
public GenreRecyclerViewHolder (View view){
super (view);
imgView = (ImageView)view.findViewById(R.id.genrepic);
tvgenre = (TextView)view.findViewById(R.id.titlegenre);
}
}
}
GenreContent.java
public class GenreContent {
private int img;
private String title;
public GenreContent(int img, String title){
this.setImg(img);
this.setTitle(title);
}
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
My Layout
TabGenre.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/genre_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
GenreLayout.xml (Custom Layout)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dip"
android:orientation="vertical">
<ImageView
android:layout_width="160dp"
android:layout_height="120dp"
android:src="#drawable/bgheader"
android:id="#+id/genrepic"/>
<TextView
android:id="#+id/titlegenre"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mystery"
android:layout_marginTop="-5dp"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
You should change this line
adaptergenre = new GenreAdapter(new ArrayList<>(arrayList));
to
adaptergenre = new GenreAdapter(arrayList);
There is new need to create new ArrayList
Related
MY PROBLEM -
my cardview is going over the screen(can be seen in the image) even if the says matchparent.
my database node
Please help....... is this a bug or smth?
What am i doing = i m trying to retrieve the data from firebase in a recycler view, the data is being retrieved but the item of the recyclerview is giving problem, as the cardview is half outside the screen even if the cardview is set to matchparent and wrapcontent please help if possible
My recycler 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">
<TextView
android:id="#+id/Cdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi"
android:textSize="50dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
</androidx.cardview.widget.CardView>
my Adapterclass
package com.sjsbhints.pdfmanager;
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.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
public class CAdapter extends FirebaseRecyclerAdapter<Cmodel,CAdapter.myViewHolder> {
/**
* Initialize a {#link RecyclerView.Adapter} that listens to a Firebase query. See
* {#link FirebaseRecyclerOptions} for configuration options.
*
* #param options
*/
public CAdapter(#NonNull FirebaseRecyclerOptions<Cmodel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull myViewHolder holder, int position, #NonNull Cmodel model) {
// if(model.Cdate.isEmpty()){
// holder.Cdate.setText("Null");
// }
holder.Cdate.setText(model.getCdate());
// holder.Cheading.setText(model.getCheading());
// holder.Cbody.setText(model.getCbody());
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.circular_item,parent,false);
return new myViewHolder(view);
}
class myViewHolder extends RecyclerView.ViewHolder{
TextView Cdate,Cheading,Cbody,Ndate,Nheading,Nsheading,Nbody,Tdate,Tsubject,Ttopic,Ttdate;
public myViewHolder(#NonNull View itemView) {
super(itemView);
Cdate = itemView.findViewById(R.id.Cdate);
// Cheading = itemView.findViewById(R.id.cheading);
// Cbody = itemView.findViewById(R.id.cbody);
}
}
}
my model class
package com.sjsbhints.pdfmanager;
public class Cmodel {
String Cdate,Cheading,Cbody,Ndate,Nheading,Nsheading,Nbody,Tdate,Tsubject,Ttopic,Ttdate;
Cmodel(){
}
public Cmodel(String cdate, String cheading, String cbody, String ndate, String nheading, String nsheading, String nbody, String tdate, String tsubject, String ttopic, String ttdate) {
Cdate = cdate;
Cheading = cheading;
Cbody = cbody;
Ndate = ndate;
Nheading = nheading;
Nsheading = nsheading;
Nbody = nbody;
Tdate = tdate;
Tsubject = tsubject;
Ttopic = ttopic;
Ttdate = ttdate;
}
public String getCdate() {
return Cdate;
}
public void setCdate(String cdate) {
Cdate = cdate;
}
public String getCheading() {
return Cheading;
}
public void setCheading(String cheading) {
Cheading = cheading;
}
public String getCbody() {
return Cbody;
}
public void setCbody(String cbody) {
Cbody = cbody;
}
public String getNdate() {
return Ndate;
}
public void setNdate(String ndate) {
Ndate = ndate;
}
public String getNheading() {
return Nheading;
}
public void setNheading(String nheading) {
Nheading = nheading;
}
public String getNsheading() {
return Nsheading;
}
public void setNsheading(String nsheading) {
Nsheading = nsheading;
}
public String getNbody() {
return Nbody;
}
public void setNbody(String nbody) {
Nbody = nbody;
}
public String getTdate() {
return Tdate;
}
public void setTdate(String tdate) {
Tdate = tdate;
}
public String getTsubject() {
return Tsubject;
}
public void setTsubject(String tsubject) {
Tsubject = tsubject;
}
public String getTtopic() {
return Ttopic;
}
public void setTtopic(String ttopic) {
Ttopic = ttopic;
}
public String getTtdate() {
return Ttdate;
}
public void setTtdate(String ttdate) {
Ttdate = ttdate;
}
}
my MainActivity
package com.sjsbhints.pdfmanager;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.FirebaseDatabase;
public class CircularAct extends AppCompatActivity {
RecyclerView recyclerView;
CAdapter cAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_circular2);
recyclerView = findViewById(R.id.rv);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerOptions<Cmodel> options =
new FirebaseRecyclerOptions.Builder<Cmodel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("CircularData"), Cmodel.class)
.build();
cAdapter = new CAdapter(options);
recyclerView.setAdapter(cAdapter);
}
#Override
protected void onStart() {
super.onStart();
cAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
cAdapter.stopListening();
}
}
my mainactivity 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=".CircularAct">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="599dp"
android:layout_height="960dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Your CardView definitely matched the parent's width because it inherited the width of the RecyclerView since that's its parent.
Your RecyclerView, on the other hand, has a width of 599dp. The fixed size means that it will ignore the device's width. To match the device's width and height, set it to match_parent or use 0dp since you're using a constraint layout in your case.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I am trying to make a program where I list the file names in a recyclerview. Using a button inside the row, the application should delete the item via a path which is stored in an array that includes the file path. The application should also display the file path if the card itself is clicked in a toast message.
So far I am able to do this, however I can only delete one file at a time when the application is active. The problem arises when I try to delete multiple files. The items are deleted from the recyclerview and everything looks normal, but if the application is closed then the files that I attempted to delete after the first one show up again, indicating that they were not deleted.
My code:
JAVA CLASSES
FileView.java (this is the main activity)
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
File[] fileList;
String filePath = "";
String fileData = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = file.listFiles();
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.length; i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList[i].getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
fileData = fileList[position].toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
#Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList[position];
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
}
});
}
}
RowAdapter.java (this is the adapter class)
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 java.util.ArrayList;
public class RowAdapter extends RecyclerView.Adapter<RowAdapter.RowViewHolder> {
private ArrayList<RowItem> mRowList;
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
void onDeleteClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class RowViewHolder extends RecyclerView.ViewHolder{
public ImageView rowImageView;
public TextView rowTextView;
public ImageView rowDeleteImage;
public RowViewHolder(#NonNull View itemView, OnItemClickListener listener) {
super(itemView);
rowImageView = itemView.findViewById(R.id.fileImage);
rowTextView = itemView.findViewById(R.id.fileName);
rowDeleteImage = itemView.findViewById(R.id.deleteFile);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
rowDeleteImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onDeleteClick(position);
}
}
}
});
}
}
public RowAdapter(ArrayList<RowItem> rowList){
mRowList = rowList;
}
#NonNull
#Override
public RowViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
RowViewHolder rvh = new RowViewHolder(v, mListener);
return rvh;
}
#Override
public void onBindViewHolder(#NonNull RowViewHolder holder, int position) {
RowItem currentItem = mRowList.get(position);
holder.rowImageView.setImageResource(currentItem.getImageResource());
holder.rowTextView.setText(currentItem.getFileName());
}
#Override
public int getItemCount() {
return mRowList.size();
}
}
RowItem.java (getters for image and filename)
public class RowItem {
private int imageResource;
private String fileName;
public RowItem(int img, String stringInput) {
this.imageResource = img;
this.fileName = stringInput;
}
public int getImageResource() {
return imageResource;
}
public String getFileName() {
return fileName;
}
}
XML FILES
activity_file_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:orientation="vertical"
tools:context="com.loopbreakr.firstpdf.FileView">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:scrollbars="vertical"
android:background="#color/cardview_shadow_start_color"
/>
</RelativeLayout>
row.xml
<?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:orientation="vertical"
android:layout_marginBottom="4dp"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp">
<ImageView
android:id="#+id/fileImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="2dp"/>
<TextView
android:id="#+id/fileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="55dp"
android:layout_marginTop="5dp"
android:text="File Name"
android:textColor="#color/black"
android:textSize="20sp" />
<ImageView
android:id="#+id/deleteFile"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_margin="5dp"
android:padding="2dp"
android:src="#drawable/ic_delete" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
EDIT
I tried to change the array to an arraylist as suggested, however I think I must have done so incorrectly as this results in a crash.
FileView.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
List<File> fileList;
String filePath = "";
String fileData = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = Arrays.asList(file.listFiles());
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.size(); i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList.get(i).getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
#Override
public void recreate() {
super.recreate();
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
fileData = fileList.get(position).toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
#Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList.get(position);
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
fileList.remove(position);
}
});
}
}
When you delete a record, the table widget (the stuff you see on your device) is updated and the row is removed. However, your fileList array is not updated; it still has the Path representing that deleted file (you deleted the file, sure, but any objects that capture the notion of the path of that file are still around, of course).
When you delete a file, you need to also fix the fileList array. Given that arrays cannot grow or shrink, this is probably a lot simpler if you use a List<File> instead of a File[].
You make it yourself difficult as you keep two lists.
rowItems and fileList.
In RowItems you have only a String variable fileName.
Add a variable String filePath and use it instead of the file list array.
I hope someone there will help me solve my problem. I have an Android application that uses the fragment. I want to download data using Volley from a JSON file. The program does not throw out any errors but CardView does not display with the ordered data. I looked at other topics with a similar problem, but I sit on it for a long time and nothing good happens.
AdapterZabytki.java
package eu.aisen.kamil.miejskiprzewodnik;
import android.support.v7.widget.CardView;
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.squareup.picasso.Picasso;
import java.util.List;
import zabytki.Zabytki;
public class AdapterZabytki extends RecyclerView.Adapter<AdapterZabytki.ViewHolder> {
private List<Zabytek>list_data;
private Zabytki context;
public AdapterZabytki(List<Zabytek> list_data, Zabytki context) {
this.list_data = list_data;
this.context = context;
}
#Override
public AdapterZabytki.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CardView view= (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.obiectcard,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Zabytek zabytek = list_data.get(position);
Picasso.get()
.load(zabytek
.getImage_url())
.into(holder.img);
holder.txtname.setText(zabytek.getName());
}
#Override
public int getItemCount() {
return list_data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private ImageView img;
private TextView txtname;
public ViewHolder(View view) {
super(view);
img=(ImageView)itemView.findViewById(R.id.info_image);
txtname=(TextView)itemView.findViewById(R.id.info_text);
}
}
}
Zabytek.java
package eu.aisen.kamil.miejskiprzewodnik;
public class Zabytek {
private String name;
private String image_url;
private String opis;
public Zabytek(String name, String image_url, String opis) {
this.name = name;
this.image_url = image_url;
this.opis = opis;
}
public String getName() {
return name;
}
public String getImage_url() {
return image_url;
}
public String getOpis() {
return opis;
}
}
Zabytki.java (fragment)
package zabytki;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import eu.aisen.kamil.miejskiprzewodnik.AdapterZabytki;
import eu.aisen.kamil.miejskiprzewodnik.R;
import eu.aisen.kamil.miejskiprzewodnik.Zabytek;
public class Zabytki extends Fragment {
private static final String HI = "https://wydzialedukacji.rzeszow.pl/testowy.json";
private ArrayList<Zabytek>list_data;
private AdapterZabytki mSensorAdapter;
private RecyclerView mRyclerView;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.zabytki_fragment, container, false);
mRyclerView = view.findViewById(R.id.main_list);
mRyclerView.setHasFixedSize(true);
mRyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
list_data = new ArrayList<>();
getData();
mSensorAdapter = new AdapterZabytki(list_data, this);
mRyclerView.setAdapter(mSensorAdapter);
mSensorAdapter.notifyDataSetChanged();
return view;
}
private void getData() {
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, HI, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("results");
for(int i=0; i < jsonArray.length(); i++){
JSONObject object = jsonArray.getJSONObject(i);
String name = object.getString("name");
String image_url = object.getString("image_url");
String opis = object.getString("opis");
list_data.add(new Zabytek(name, image_url, opis));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
Volley.newRequestQueue(getActivity()).add(request);
}
}
zabytki_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView android:id="#+id/main_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
</android.support.v7.widget.RecyclerView>
obiectcard.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/card_view"
android:layout_margin="5dp"
card_view:cardCornerRadius="4dp">
<android.support.constraint.ConstraintLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp">
<ImageView
android:id="#+id/info_image"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="24dp"
android:layout_weight="1.0"
android:scaleType="centerCrop"
card_view:layout_constraintBottom_toBottomOf="parent"
card_view:srcCompat="#android:drawable/sym_def_app_icon"
tools:ignore="MissingConstraints" />
<TextView
android:id="#+id/info_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginEnd="16dp"
android:text="tytułzabytku"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintTop_toBottomOf="#+id/info_image" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
I have 2 concerns about your code:
1. in onResponse, after you added all items to to list_data, you must call notifyDatasetChanged on RecyclerView adapter (AdapterZabytki)
2. Also, info_image in your ViewHolder seems to have zero height, because it has no top alignment and layout_height="0dp"
I am still wondering how to transfer this data to ZabytekDetailActivity.class
I have this:
mSensorAdapter.setListener(new AdapterZabytki.Listener() {
public void onClick(int position) {
ArrayList<Zabytek> object = new ArrayList<Zabytek>();
Intent intent = new Intent(getActivity(), ZabytekDetailActivity.class);
}
});
Now the question is how to attach the results from list_data so that they can be displayed in MonumentDetailActivity.class
I've been trying to implement a simple scrollable list that gets its data from Firebase Database using RecyclerView on an activity called MyOrganisedEventsActivity. Problem is, when my main activity starts the MyOrganisedEventsActivity, there is no call made to the method onCreateViewHolder, and thus the RecyclerView is empty.
However, after waiting a moment and then locking and unlocking my phone, a call is made to onCreateViewHolder and the list items start appearing on the RecyclerView. Is there anyway to force the call when the activity is first started? Or is there something wrong with my code and how can I fix it?
Here's my code so far:
MyOrganisedEventsActivity.java:
package com.llawl.tristonpang.intheloop;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MyOrganisedEventsActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private OrganisedEventsAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private List<EventInfo> mEventsDataset;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_organised_events);
mRecyclerView = (RecyclerView) findViewById(R.id.org_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mEventsDataset = new ArrayList<>();
// specify an adapter (see also next example)
mAdapter = new OrganisedEventsAdapter(mEventsDataset);
mRecyclerView.setAdapter(mAdapter);
prepareEventsData();
}
private void prepareEventsData() {
final String currentUser = FirebaseAuth.getInstance().getCurrentUser().getEmail();
Log.d("InTheLoop", "prepareEventsData(), currentUser = " + currentUser);
FirebaseDatabase.getInstance().getReference().child("events_info").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
//EventInfo event = snapshot.getValue(EventInfo.class);
HashMap<String,String> data = (HashMap) snapshot.getValue();
//Log.d("InTheLoop", "Event name: " + event.getName());
//if (event.getOrganiser().equals(currentUser)) {
if (data.get("organiser").equals(currentUser)) {
Log.d("InTheLoop", "Adding event: " + data.get("name"));
EventInfo event = new EventInfo(data.get("name"), data.get("date"), data.get("time"), data.get("venue"),
data.get("desc"), data.get("imageName"), data.get("organiser"));
mEventsDataset.add(event);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mAdapter.notifyDataSetChanged();
}
}
OrganisedEventsAdapter.java:
package com.llawl.tristonpang.intheloop;
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.TextView;
import java.util.List;
public class OrganisedEventsAdapter extends RecyclerView.Adapter<OrganisedEventsAdapter.ViewHolder> {
private List<EventInfo> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mName;
public TextView mVenue;
public TextView mDate;
public ViewHolder(View v) {
super(v);
mName = v.findViewById(R.id.org_row_name);
mVenue = v.findViewById(R.id.org_row_venue);
mDate = v.findViewById(R.id.org_row_date);
}
}
public OrganisedEventsAdapter(List<EventInfo> dataset) {
mDataset = dataset;
}
// Create new views (invoked by the layout manager)
#Override
public OrganisedEventsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.organised_event_row, parent, false);
Log.d("InTheLoop", "Adapter, onCreateViewHolder");
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
EventInfo event = mDataset.get(position);
Log.d("InTheLoop", "Adapter, Event name: " + event.getName());
holder.mName.setText(event.getName());
holder.mVenue.setText(event.getVenue());
holder.mDate.setText(event.getDate());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
EventInfo.java:
package com.llawl.tristonpang.intheloop;
public class EventInfo {
private String mName;
private String mDate;
private String mTime;
private String mVenue;
private String mDesc;
private String mImageName;
private String mOrganiser;
public EventInfo() {
}
public EventInfo(String name, String date, String time, String venue, String desc, String imageName, String organiser) {
mName = name;
mDate = date;
mTime = time;
mVenue = venue;
mDesc = desc;
mImageName = imageName;
mOrganiser = organiser;
}
public String getName() {
return mName;
}
public String getDate() {
return mDate;
}
public String getTime() {
return mTime;
}
public String getVenue() {
return mVenue;
}
public String getDesc() {
return mDesc;
}
public String getImageName() {
return mImageName;
}
public String getOrganiser() {
return mOrganiser;
}
}
organised_event_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/single_event_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:paddingBottom="#dimen/row_padding_vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/row_padding_vertical">
<TextView
android:id="#+id/org_row_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="name"
android:textColor="#color/black"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/org_row_venue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/org_row_name"
android:text="venue" />
<TextView
android:id="#+id/org_row_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="date"
android:textColor="#color/black" />
</RelativeLayout>
activity_my_organised_events.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".MyOrganisedEventsActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/org_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
Any help is much appreciated! Thanks!
Move mAdapter.notifyDataSetChanged(); inside onDataChange(DataSnapshot dataSnapshot) . You have missed the nature of asynchronous call.
FirebaseDatabase.getInstance().getReference().child("events_info").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
// Build data here
}
mAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
call mAdapter.notifyDataSetChanged(); after you add data in List in for loop in onDataChange()
so basically add data in your data structure and then notify adapter to update itself with new data.
Am trying to use a sugar orm database to store image and text, but nothing is been displayed on the recylerview although am getting a confirmation that data is been stored in my database. This is the bit of code from my MainActivity.class that is saving value to the database, as well as to display the saved data to the recyclerview. But my problem is that its not showing anything when I run my code. Please help!
recyclerView =(RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
imagepojo = new ImageSugarPojo();
int image = imagepojo.setImage(R.drawable.atama);
String text = imagepojo.setText("Soup");
imageSugar = new ArrayList<ImageSugarPojo>();
imageSugar.add(new ImageSugarPojo( image,text));
imagepojo.save();
long count = ImageSugarPojo.count(ImageSugarPojo.class);
Log.i("Count: ",String.valueOf(count));
imageSugar = new ArrayList<ImageSugarPojo>();
imageSugar = ImageSugarPojo.listAll(ImageSugarPojo.class);
recyclerAdapter = new RecyclerAdapter(this,imageSugar);
recyclerView.setAdapter(recyclerAdapter);
recyclerAdapter.notifyDataSetChanged();
I replicated your code since you said my first solution did not work for you.
This is the ImageSugarPojo class it is the same with yours
import com.orm.SugarRecord;
public class ImageSugarPojo extends SugarRecord{
private String image;
private String text;
public ImageSugarPojo(){}
public ImageSugarPojo(String image, String text){
this.image =image;
this.text = text;
}
public String getImage() {
return image;
}
public void setImage(String image) {
image = image;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
The ViewHolder class for the Adapter is like this
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class CategoryViewHolder extends RecyclerView.ViewHolder{
public TextView categoryName;
public ImageView categoryImage;
public View mItemView;
public CategoryViewHolder(View itemView) {
super(itemView);
mItemView = itemView;
categoryName = (TextView)itemView.findViewById(R.id.category_name);
categoryImage = (ImageView)itemView.findViewById(R.id.category_image);
}
}
In the adapter class, you can see that I stored the image and text as String since it is hard to store image resource id as int in Sugar ORM database.
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public class CategoryAdapter extends RecyclerView.Adapter<CategoryViewHolder>{
private Context context;
private List<ImageSugarPojo> categoryObject;
public CategoryAdapter(Context context, List<ImageSugarPojo> categoryObject) {
this.context = context;
this.categoryObject = categoryObject;
}
#Override
public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_category_list, parent, false);
return new CategoryViewHolder(layoutView);
}
#Override
public void onBindViewHolder(CategoryViewHolder holder, int position) {
final ImageSugarPojo catObject = categoryObject.get(position);
holder.categoryName.setText(catObject.getText());
int resId = getResourseId(context, "drawable", catObject.getImage(), context.getPackageName());
}
#Override
public int getItemCount() {
return categoryObject.size();
}
public static int getResourseId(Context context, String pVariableName, String pResourcename, String pPackageName) throws RuntimeException {
try {
return context.getResources().getIdentifier(pVariableName, pResourcename, pPackageName);
} catch (Exception e) {
throw new RuntimeException("Error getting Resource ID.", e);
}
}
}
The layout file for the adapter class is simple
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:id="#+id/category_image"
android:layout_width="200dp"
android:layout_height="150dp"
android:adjustViewBounds="true"
android:contentDescription="#string/app_name"
android:src="#drawable/sandals" />
<TextView
android:id="#+id/category_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="#string/pizza"
android:textColor="#color/colorPrimaryDark"
android:textSize="14dp"
android:textStyle="bold" />
</LinearLayout>
The MainActivity class
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageSugarPojo imagepojo = new ImageSugarPojo();
imagepojo.setImage("sandals");
imagepojo.setText("Soup");
imagepojo.save();
long count = ImageSugarPojo.count(ImageSugarPojo.class);
Log.i("Count: ",String.valueOf(count));
Log.i("Display: ",String.valueOf(imagepojo.getImage()));
recyclerView = (RecyclerView)findViewById(R.id.category_menu);
GridLayoutManager mGrid = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(mGrid);
recyclerView.setHasFixedSize(true);
List<ImageSugarPojo> imageSugar = ImageSugarPojo.listAll(ImageSugarPojo.class);
CategoryAdapter mAdapter = new CategoryAdapter(this, imageSugar);
recyclerView.setAdapter(mAdapter);
}
}
This is the result