I'm having trouble setting the text of multiple textviews in a custom list layout with a custom adapter. Here is my list item layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip" >
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dp"
android:contentDescription="TODO"
android:src="#drawable/blue_circle" />
<TextView
android:id="#+id/short_content"
android:layout_width="wrap_content"
android:layout_height="26dip"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#id/icon"
android:ellipsize="marquee"
android:text="content"
android:singleLine="true"
android:textSize="12sp" />
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/short_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_toRightOf="#id/icon"
android:gravity="center_vertical"
android:text="Title"
android:textSize="16sp" />
<TextView
android:id="#+id/date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/short_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/icon"
android:gravity="right"
android:text="date"
android:textSize="13sp" />
Here is my adapter:
public class MessageAdapter extends ArrayAdapter<TextContent> {
public MessageAdapter(Context context, int textViewResourceId){
super(context, textViewResourceId);
}
public MessageAdapter(Context context, int textViewResourceId, List<TextContent> items){
super(context, textViewResourceId, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater;
inflater = LayoutInflater.from(getContext());
view = inflater.inflate(R.layout.messages_layout, null);
}
TextContent p = getItem(position);
if(p != null) {
TextView textViewShortContent = (TextView) view.findViewById(R.id.short_content);
TextView textViewTitle = (TextView) view.findViewById(R.id.title);
TextView textViewDate = (TextView) view.findViewById(R.id.date);
if (textViewShortContent != null) {
textViewShortContent.setText("Short Content");
}
if (textViewTitle != null) {
textViewTitle.setText("TITLE");
}
if (textViewDate != null) {
textViewDate.setText("DATE");
}
}
return view;
}
}
here is my textContent class:
public class TextContent implements Serializable{
private String GUID, created, modified, deleted, name, message, title, shortContent, fullContent, author, language, person;
public TextContent(){
}
public TextContent(String GUID, String created, String modified, String deleted, String name, String message, String title,
String shortContent, String fullContent, String author, String language, String person) {
this.GUID = GUID;
this.created = created;
this.modified = modified;
this.deleted = deleted;
this.name = name;
this.message = message;
this.title = title;
this.shortContent = shortContent;
this.fullContent = fullContent;
this.author = author;
this.language = language;
this.person = person;
}
public String getGUID() {
return GUID;
}
public String getCreated() {
return created;
}
public String getModified() {
return modified;
}
public String getDeleted() {
return deleted;
}
public String getName() {
return name;
}
public String getMessage() {
return message;
}
public String getTitle() {
return title;
}
public String getShortContent() {
return shortContent;
}
public String getFullContent() {
return fullContent;
}
public String getAuthor() {
return author;
}
public String getLanguage() {
return language;
}
public String getPerson() {
return person;
}
public void setGUID(String GUID) {
this.GUID = GUID;
}
public void setCreated(String created) {
this.created = created;
}
public void setModified(String modified) {
this.modified = modified;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public void setName(String name) {
this.name = name;
}
public void setMessage(String message) {
this.message = message;
}
public void setTitle(String title) {
this.title = title;
}
public void setShortContent(String shortContent) {
this.shortContent = shortContent;
}
public void setFullContent(String fullContent) {
this.fullContent = fullContent;
}
public void setAuthor(String author) {
this.author = author;
}
public void setLanguage(String language) {
this.language = language;
}
public void setPerson(String person) {
this.person = person;
}
}
and here is where I instantiate my adapter
listView = (ListView) getView().findViewById(R.id.list_view_messages);
MessageAdapter adapter = new MessageAdapter(context, R.layout.messages_layout, textContentList);
listView.setAdapter(adapter);
The only thing that gets displayed is the getShortContent but not getTitle or getCreated for some reason. I am 100% certain that text has been set for all fields of the textContent.
I figured it out. The textViews in my layout was overlapping so the content from the other textviews got hidden behind.
Related
I want to list the cities and their temperatures with the recyclerview via the api, but I can't see the data. I'm new to this, can you help me?
My Code:
public class MainActivity extends AppCompatActivity {
public static String apikey = "blablabla";
public static String lan = "55.5";
public static String lon="37.5";
public static String cnt="10";
private List<CountryData> list;
SearchView searchView;
RecyclerView countries;
TextView countryName, temperature;
ImageView image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchView = (SearchView) findViewById(R.id.searchView);
countries = (RecyclerView) findViewById(R.id.countries);
countryName = (TextView) findViewById(R.id.countryName);
temperature = (TextView) findViewById(R.id.temperature);
image = (ImageView) findViewById(R.id.image);
list = new ArrayList<>();
countries = findViewById(R.id.countries);
countries.setLayoutManager(new LinearLayoutManager(this));
countries.setHasFixedSize(true);
Adapter adapter = new Adapter(this, list);
countries.setAdapter(adapter);
ApiUtilities.getApiInterface().getCountryData(lan,lon,cnt,apikey).enqueue(new Callback<List<CountryData>>(){
#Override
public void onResponse(Call<List<CountryData>> call, Response<List<CountryData>> response) {
if (response.code() == 200) {
RetrofitModel retrofitModel = (RetrofitModel) response.body();
assert retrofitModel != null;
double temp = retrofitModel.main.temp - 273.15;
int tempToInt = (int) temp;
String country = retrofitModel.sys.country;
for(int i=0; i<list.size(); i++){
countryName.setText(country);
}
String temperatures = tempToInt + "°C";
temperature.setText(temperatures);
}
}
#Override
public void onFailure(Call<List<CountryData>> call, Throwable t) {
}
});
}
}
API CONTROLLER
public interface APIController {
String BASE_URL = "https://api.openweathermap.org/data/2.5/";
#GET("find?lat=55.5&lon=37.5&cnt=10&appid=3f8c9db425f5691cb59026f85546237e")
//Call<List<CountryData>> getCountryData();
Call<List<CountryData>> getCountryData(#Query("lat") String lat, #Query("lon") String lon, #Query("cnt") String cnt , #Query("APIKey") String apiKey);
}
RETROFİT MODEL
class RetrofitModel {
#SerializedName("list")
private String list;
private String country;
private String name;
private String temp;
#SerializedName("coord")
public Coord coord;
#SerializedName("sys")
public Sys sys;
#SerializedName("weather")
public ArrayList<Weather> weather = new ArrayList<Weather>();
#SerializedName("main")
public Main main;
public String getList() {
return list;
}
public void setList(String list) {
this.list = list;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public ArrayList<Weather> getWeather() {
return weather;
}
public void setWeather(ArrayList<Weather> weather) {
this.weather = weather;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public RetrofitModel(String list, String country, String name, String temp, Coord coord, Sys sys, ArrayList<Weather> weather, Main main) {
this.list = list;
this.country = country;
this.name = name;
this.temp = temp;
this.coord = coord;
this.sys = sys;
this.weather = weather;
this.main = main;
}
}
class Weather {
#SerializedName("id")
public int id;
#SerializedName("main")
public String main;
}
class Main {
#SerializedName("temp")
public float temp;
}
class Sys {
#SerializedName("country")
public String country;
public Sys(String country) {
this.country = country;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
class Coord {
#SerializedName("lon")
public float lon;
#SerializedName("lat")
public float lat;
}
COUNTRY DATA
public class CountryData {
#SerializedName("list")
private String list;
private String country;
private String name;
private String temp;
public CountryData(String list, String country, String name, String temp) {
this.list = list;
this.country = country;
this.name = name;
this.temp = temp;
}
public String getList() {
return list;
}
public void setList(String list) {
this.list = list;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
}
XML CODES
<?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">
<SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#drawable/weather"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="30dp"
android:textColor="#color/black"
android:text="Country Name"
android:textSize="15dp" ></TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="30dp"
android:text="Temperature"
androi
d:textColor="#color/black"
android:textSize="15dp" >
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/countries"
tools:listitem="#layout/country_item_layout"
app:layoutManager="LinearLayoutManager"
/>
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardElevation="3dp"
android:layout_marginHorizontal="8dp"
android:layout_marginTop="8dp"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="7dp"
android:layout_marginHorizontal="15dp">
<TextView
android:id="#+id/countryName"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_alignParentStart="true"
android:layout_marginEnd="30dp"
android:textColor="#color/black"
android:text="Türkiye"
android:layout_centerVertical="true"
android:gravity="center"
android:textSize="15dp" ></TextView>
<TextView
android:id="#+id/temperature"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="30dp"
android:textColor="#color/black"
android:text="Temperature"
android:layout_centerVertical="true"
android:gravity="center"
android:textSize="15dp" ></TextView>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
hello, I want to list the cities and their temperatures with the recyclerview via the api, but I can't see the data. I'm new to this, can you help me?
You can easy to implement in Volley
implementation 'com.android.volley:volley:1.2.0'
In Java Code:
queue = Volley.newRequestQueue(this); // RequestQueue
String url = "https://api.openweathermap.org/data/2.5/find?lat=55.5&lon=37.5&cnt=10&appid=3f8c9db425f5691cb59026f85546237e";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("list");
for (int i = 0 ; i<jsonArray.length() ; i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
resultText.append("ID : " + id + "\nName : " + name + "\n\n"); // TextView
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}}
) ;
queue.add(request);
Output:
I am trying to display my data from firebase real time database on a listview in the main menu screen once the users log in. The app is running but its not displaying the data.
This is the data in my database
Now for the codes.
MainMenu.java This function is called on the OnCreate().
public void makeItem ()
{
lv = findViewById(R.id.listView);
db = FirebaseDatabase.getInstance().getReference();
helper = new FirebaseHelper(db);
adapter= new AdapterItem(this,helper.retrive());
lv.setAdapter(adapter);
}
CustomListAdapter.java
public class CustomListAdapter{
private String ItemName;
private String Quantity;
private String SerialNo;
private String SupplierName;
private String SupplierEmail;
private String SupplierPhone;
public CustomListAdapter(){
}
public CustomListAdapter (String ItemName,String Quantity,String SerialNo,String SupplierName,String SupplierEmail,String SupplierPhone)
{
this.ItemName = ItemName;
this.Quantity = Quantity;
this.SerialNo = SerialNo;
this.SupplierName = SupplierName;
this.SupplierEmail = SupplierEmail;
this.SupplierPhone = SupplierPhone;
}
public void setItemName (String ItemName)
{
this.ItemName = ItemName;
}
public String getItemName ()
{
return ItemName;
}
public void setQuantity (String Quantity)
{
this.Quantity = Quantity;
}
public String getQuantity ()
{
return Quantity;
}
public void setSerialNo (String SerialNo)
{
this.SerialNo = SerialNo;
}
public String getSerialNo ()
{
return SerialNo;
}
public void setSupplierName (String SupplierName)
{
this.SupplierName = SupplierName;
}
public String getSupplierName()
{
return SupplierName;
}
public void setSupplierEmail (String SupplierEmail)
{
this.SupplierEmail = SupplierEmail;
}
public String getSupplierEmail() {
return SupplierEmail;
}
public void setSupplierPhone (String SupplierPhone)
{
this.SupplierPhone = SupplierPhone;
}
public String getSupplierPhone() {
return SupplierPhone;
}
}
AdapterItem.java
public class AdapterItem extends BaseAdapter {
Context c;
ArrayList<CustomListAdapter> customListAdapters;
public AdapterItem(Context c, ArrayList<CustomListAdapter> customListAdapters) {
this.c = c;
this.customListAdapters = customListAdapters;
}
#Override
public int getCount() {
return customListAdapters.size();
}
#Override
public Object getItem(int position) {
return customListAdapters.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null)
{
convertView=LayoutInflater.from(c).inflate(R.layout.content_main_menu_list,parent,false);
}
TextView ItemName = convertView.findViewById(R.id.name);
TextView SerialNo = convertView.findViewById(R.id.serialNo);
TextView SupplierName = convertView.findViewById(R.id.supplierName);
TextView amount = convertView.findViewById(R.id.amount);
final CustomListAdapter CLA = (CustomListAdapter) this.getItem(position);
ItemName.setText(CLA.getItemName());
SerialNo.setText(CLA.getSerialNo());
SupplierName.setText(CLA.getSupplierName());
amount.setText(CLA.getQuantity());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(c,CLA.getItemName(),Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
content_main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_main_menu">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp" />
content_main_menu_list.xml is a custom layout that i created for every data set to be displayed.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="#+id/serialNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/supplierName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintTop_toBottomOf="#+id/serialNo" />
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="23dp"
android:layout_marginBottom="8dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#0171B0"
app:layout_constraintBottom_toTopOf="#+id/serialNo" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
The problem in your code lies in the fact that you have in your CustomListAdapter class a field named ItemName but you are using a getter named getItemName(), which is not correct since Firebase is looking in the database for a field named itemName and not ItemName. See the lowercase i letter vs. capital letter I?
There are two ways in which you can solve this problem. The first one would be to change your model class by renaming the fields according to the Java Naming Conventions. So you model class should look like this:
public class CustomListAdapter {
private String itemName, quantity, serialNo, supplierName, supplierEmail, supplierPhone;
public CustomListAdapter() {}
public CustomListAdapter(String itemName, String quantity, String serialNo, String supplierName, String supplierEmail, String supplierPhone) {
this.itemName = itemName;
this.quantity = quantity;
this.serialNo = serialNo;
this.supplierName = supplierName;
this.supplierEmail = supplierEmail;
this.supplierPhone = supplierPhone;
}
public String getItemName() { return itemName; }
public String getQuantity() { return quantity; }
public String getSerialNo() { return serialNo; }
public String getSupplierName() { return supplierName; }
public String getSupplierEmail() { return supplierEmail; }
public String getSupplierPhone() { return supplierPhone; }
}
See in this example, there are private fields and public getters. There is also a simpler solution, to set the value directly on public fields like this:
public class CustomListAdapter {
public String itemName, quantity, serialNo, supplierName, supplierEmail, supplierPhone;
}
Now just remove the current data and add it again using the correct names. This solution will work only if you are in testing phase.
There is also the second approach, which is to use annotations. So if you prefer to use private fields and public getters, you should use the PropertyName annotation only in front of the getter. So your CustomListAdapter class should look like this:
public class CustomListAdapter {
private String ItemName;
private String Quantity;
private String SerialNo;
private String SupplierName;
private String SupplierEmail;
private String SupplierPhone;
public CustomListAdapter() {}
public CustomListAdapter(String itemName, String quantity, String serialNo, String supplierName, String supplierEmail, String supplierPhone) {
ItemName = itemName;
Quantity = quantity;
SerialNo = serialNo;
SupplierName = supplierName;
SupplierEmail = supplierEmail;
SupplierPhone = supplierPhone;
}
#PropertyName("ItemName")
public String getItemName() { return ItemName; }
#PropertyName("Quantity")
public String getQuantity() { return Quantity; }
#PropertyName("SerialNo")
public String getSerialNo() { return SerialNo; }
#PropertyName("SupplierName")
public String getSupplierName() { return SupplierName; }
#PropertyName("SupplierEmail")
public String getSupplierEmail() { return SupplierEmail; }
#PropertyName("SupplierPhone")
public String getSupplierPhone() { return SupplierPhone; }
}
I am trying to display my data from firebase real time database on a listview in the main menu screen once the users log in. The app is running but its not displaying the data.
This is the data in my database
Now for the codes.
MainMenu.java This function is called on the OnCreate().
public void makeItem ()
{
lv = findViewById(R.id.listView);
db = FirebaseDatabase.getInstance().getReference();
helper = new FirebaseHelper(db);
adapter= new AdapterItem(this,helper.retrive());
lv.setAdapter(adapter);
}
CustomListAdapter.java
public class CustomListAdapter{
private String ItemName;
private String Quantity;
private String SerialNo;
private String SupplierName;
private String SupplierEmail;
private String SupplierPhone;
public CustomListAdapter(){
}
public CustomListAdapter (String ItemName,String Quantity,String SerialNo,String SupplierName,String SupplierEmail,String SupplierPhone)
{
this.ItemName = ItemName;
this.Quantity = Quantity;
this.SerialNo = SerialNo;
this.SupplierName = SupplierName;
this.SupplierEmail = SupplierEmail;
this.SupplierPhone = SupplierPhone;
}
public void setItemName (String ItemName)
{
this.ItemName = ItemName;
}
public String getItemName ()
{
return ItemName;
}
public void setQuantity (String Quantity)
{
this.Quantity = Quantity;
}
public String getQuantity ()
{
return Quantity;
}
public void setSerialNo (String SerialNo)
{
this.SerialNo = SerialNo;
}
public String getSerialNo ()
{
return SerialNo;
}
public void setSupplierName (String SupplierName)
{
this.SupplierName = SupplierName;
}
public String getSupplierName()
{
return SupplierName;
}
public void setSupplierEmail (String SupplierEmail)
{
this.SupplierEmail = SupplierEmail;
}
public String getSupplierEmail() {
return SupplierEmail;
}
public void setSupplierPhone (String SupplierPhone)
{
this.SupplierPhone = SupplierPhone;
}
public String getSupplierPhone() {
return SupplierPhone;
}
}
AdapterItem.java
public class AdapterItem extends BaseAdapter {
Context c;
ArrayList<CustomListAdapter> customListAdapters;
public AdapterItem(Context c, ArrayList<CustomListAdapter> customListAdapters) {
this.c = c;
this.customListAdapters = customListAdapters;
}
#Override
public int getCount() {
return customListAdapters.size();
}
#Override
public Object getItem(int position) {
return customListAdapters.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null)
{
convertView=LayoutInflater.from(c).inflate(R.layout.content_main_menu_list,parent,false);
}
TextView ItemName = convertView.findViewById(R.id.name);
TextView SerialNo = convertView.findViewById(R.id.serialNo);
TextView SupplierName = convertView.findViewById(R.id.supplierName);
TextView amount = convertView.findViewById(R.id.amount);
final CustomListAdapter CLA = (CustomListAdapter) this.getItem(position);
ItemName.setText(CLA.getItemName());
SerialNo.setText(CLA.getSerialNo());
SupplierName.setText(CLA.getSupplierName());
amount.setText(CLA.getQuantity());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(c,CLA.getItemName(),Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
content_main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_main_menu">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp" />
content_main_menu_list.xml is a custom layout that i created for every data set to be displayed.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="#+id/serialNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/supplierName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintTop_toBottomOf="#+id/serialNo" />
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="23dp"
android:layout_marginBottom="8dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#0171B0"
app:layout_constraintBottom_toTopOf="#+id/serialNo" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
The problem in your code lies in the fact that you have in your CustomListAdapter class a field named ItemName but you are using a getter named getItemName(), which is not correct since Firebase is looking in the database for a field named itemName and not ItemName. See the lowercase i letter vs. capital letter I?
There are two ways in which you can solve this problem. The first one would be to change your model class by renaming the fields according to the Java Naming Conventions. So you model class should look like this:
public class CustomListAdapter {
private String itemName, quantity, serialNo, supplierName, supplierEmail, supplierPhone;
public CustomListAdapter() {}
public CustomListAdapter(String itemName, String quantity, String serialNo, String supplierName, String supplierEmail, String supplierPhone) {
this.itemName = itemName;
this.quantity = quantity;
this.serialNo = serialNo;
this.supplierName = supplierName;
this.supplierEmail = supplierEmail;
this.supplierPhone = supplierPhone;
}
public String getItemName() { return itemName; }
public String getQuantity() { return quantity; }
public String getSerialNo() { return serialNo; }
public String getSupplierName() { return supplierName; }
public String getSupplierEmail() { return supplierEmail; }
public String getSupplierPhone() { return supplierPhone; }
}
See in this example, there are private fields and public getters. There is also a simpler solution, to set the value directly on public fields like this:
public class CustomListAdapter {
public String itemName, quantity, serialNo, supplierName, supplierEmail, supplierPhone;
}
Now just remove the current data and add it again using the correct names. This solution will work only if you are in testing phase.
There is also the second approach, which is to use annotations. So if you prefer to use private fields and public getters, you should use the PropertyName annotation only in front of the getter. So your CustomListAdapter class should look like this:
public class CustomListAdapter {
private String ItemName;
private String Quantity;
private String SerialNo;
private String SupplierName;
private String SupplierEmail;
private String SupplierPhone;
public CustomListAdapter() {}
public CustomListAdapter(String itemName, String quantity, String serialNo, String supplierName, String supplierEmail, String supplierPhone) {
ItemName = itemName;
Quantity = quantity;
SerialNo = serialNo;
SupplierName = supplierName;
SupplierEmail = supplierEmail;
SupplierPhone = supplierPhone;
}
#PropertyName("ItemName")
public String getItemName() { return ItemName; }
#PropertyName("Quantity")
public String getQuantity() { return Quantity; }
#PropertyName("SerialNo")
public String getSerialNo() { return SerialNo; }
#PropertyName("SupplierName")
public String getSupplierName() { return SupplierName; }
#PropertyName("SupplierEmail")
public String getSupplierEmail() { return SupplierEmail; }
#PropertyName("SupplierPhone")
public String getSupplierPhone() { return SupplierPhone; }
}
I am trying to display my data from firebase real time database on a listview in the main menu screen once the users log in. The app is running but its not displaying the data.
This is the data in my database
Now for the codes.
MainMenu.java This function is called on the OnCreate().
public void makeItem ()
{
lv = findViewById(R.id.listView);
db = FirebaseDatabase.getInstance().getReference();
helper = new FirebaseHelper(db);
adapter= new AdapterItem(this,helper.retrive());
lv.setAdapter(adapter);
}
CustomListAdapter.java
public class CustomListAdapter{
private String ItemName;
private String Quantity;
private String SerialNo;
private String SupplierName;
private String SupplierEmail;
private String SupplierPhone;
public CustomListAdapter(){
}
public CustomListAdapter (String ItemName,String Quantity,String SerialNo,String SupplierName,String SupplierEmail,String SupplierPhone)
{
this.ItemName = ItemName;
this.Quantity = Quantity;
this.SerialNo = SerialNo;
this.SupplierName = SupplierName;
this.SupplierEmail = SupplierEmail;
this.SupplierPhone = SupplierPhone;
}
public void setItemName (String ItemName)
{
this.ItemName = ItemName;
}
public String getItemName ()
{
return ItemName;
}
public void setQuantity (String Quantity)
{
this.Quantity = Quantity;
}
public String getQuantity ()
{
return Quantity;
}
public void setSerialNo (String SerialNo)
{
this.SerialNo = SerialNo;
}
public String getSerialNo ()
{
return SerialNo;
}
public void setSupplierName (String SupplierName)
{
this.SupplierName = SupplierName;
}
public String getSupplierName()
{
return SupplierName;
}
public void setSupplierEmail (String SupplierEmail)
{
this.SupplierEmail = SupplierEmail;
}
public String getSupplierEmail() {
return SupplierEmail;
}
public void setSupplierPhone (String SupplierPhone)
{
this.SupplierPhone = SupplierPhone;
}
public String getSupplierPhone() {
return SupplierPhone;
}
}
AdapterItem.java
public class AdapterItem extends BaseAdapter {
Context c;
ArrayList<CustomListAdapter> customListAdapters;
public AdapterItem(Context c, ArrayList<CustomListAdapter> customListAdapters) {
this.c = c;
this.customListAdapters = customListAdapters;
}
#Override
public int getCount() {
return customListAdapters.size();
}
#Override
public Object getItem(int position) {
return customListAdapters.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null)
{
convertView=LayoutInflater.from(c).inflate(R.layout.content_main_menu_list,parent,false);
}
TextView ItemName = convertView.findViewById(R.id.name);
TextView SerialNo = convertView.findViewById(R.id.serialNo);
TextView SupplierName = convertView.findViewById(R.id.supplierName);
TextView amount = convertView.findViewById(R.id.amount);
final CustomListAdapter CLA = (CustomListAdapter) this.getItem(position);
ItemName.setText(CLA.getItemName());
SerialNo.setText(CLA.getSerialNo());
SupplierName.setText(CLA.getSupplierName());
amount.setText(CLA.getQuantity());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(c,CLA.getItemName(),Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
content_main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_main_menu">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp" />
content_main_menu_list.xml is a custom layout that i created for every data set to be displayed.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="#+id/serialNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/supplierName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintTop_toBottomOf="#+id/serialNo" />
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="23dp"
android:layout_marginBottom="8dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#0171B0"
app:layout_constraintBottom_toTopOf="#+id/serialNo" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
The problem in your code lies in the fact that you have in your CustomListAdapter class a field named ItemName but you are using a getter named getItemName(), which is not correct since Firebase is looking in the database for a field named itemName and not ItemName. See the lowercase i letter vs. capital letter I?
There are two ways in which you can solve this problem. The first one would be to change your model class by renaming the fields according to the Java Naming Conventions. So you model class should look like this:
public class CustomListAdapter {
private String itemName, quantity, serialNo, supplierName, supplierEmail, supplierPhone;
public CustomListAdapter() {}
public CustomListAdapter(String itemName, String quantity, String serialNo, String supplierName, String supplierEmail, String supplierPhone) {
this.itemName = itemName;
this.quantity = quantity;
this.serialNo = serialNo;
this.supplierName = supplierName;
this.supplierEmail = supplierEmail;
this.supplierPhone = supplierPhone;
}
public String getItemName() { return itemName; }
public String getQuantity() { return quantity; }
public String getSerialNo() { return serialNo; }
public String getSupplierName() { return supplierName; }
public String getSupplierEmail() { return supplierEmail; }
public String getSupplierPhone() { return supplierPhone; }
}
See in this example, there are private fields and public getters. There is also a simpler solution, to set the value directly on public fields like this:
public class CustomListAdapter {
public String itemName, quantity, serialNo, supplierName, supplierEmail, supplierPhone;
}
Now just remove the current data and add it again using the correct names. This solution will work only if you are in testing phase.
There is also the second approach, which is to use annotations. So if you prefer to use private fields and public getters, you should use the PropertyName annotation only in front of the getter. So your CustomListAdapter class should look like this:
public class CustomListAdapter {
private String ItemName;
private String Quantity;
private String SerialNo;
private String SupplierName;
private String SupplierEmail;
private String SupplierPhone;
public CustomListAdapter() {}
public CustomListAdapter(String itemName, String quantity, String serialNo, String supplierName, String supplierEmail, String supplierPhone) {
ItemName = itemName;
Quantity = quantity;
SerialNo = serialNo;
SupplierName = supplierName;
SupplierEmail = supplierEmail;
SupplierPhone = supplierPhone;
}
#PropertyName("ItemName")
public String getItemName() { return ItemName; }
#PropertyName("Quantity")
public String getQuantity() { return Quantity; }
#PropertyName("SerialNo")
public String getSerialNo() { return SerialNo; }
#PropertyName("SupplierName")
public String getSupplierName() { return SupplierName; }
#PropertyName("SupplierEmail")
public String getSupplierEmail() { return SupplierEmail; }
#PropertyName("SupplierPhone")
public String getSupplierPhone() { return SupplierPhone; }
}
I am trying to create recyclerview inside recyclerview which is retrieving the data from Firebase.
So far, I have two recyclerview adapters. GenreAdapter and AnimeInsideGenreAdapter classes.
I was able to show GenreAdapter data into my HomeFragment, but the AnimeInsideGenreAdapter is not showing any data and I have no idea why. I've been looking for my problem on Google but still not getting any luck.
So here are my classes and layouts:
GenreAdapter.class
public class GenreAdapter extends RecyclerView.Adapter {
private List<Genre> genreList;
private Context context;
private List<Anime> perAnimes;
private RecyclerView rvPerAnime;
private RecyclerView.Adapter adapterPerAnime;
class ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
FontAppCompatTextView genre_id, genre_title;
LinearLayout main;
public ViewHolder(final View itemView) {
super(itemView);
main = itemView.findViewById(R.id.main_layout);
genre_id = itemView.findViewById(R.id.genre_id);
genre_title = itemView.findViewById(R.id.genre_title);
}
}
public GenreAdapter(List<Genre> genreList, Context context) {
this.genreList = genreList;
this.context = context;
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_genre, parent, false));
}
public void onBindViewHolder(ViewHolder holder, int position) {
Genre genre = this.genreList.get(position);
holder.genre_id.setText(genre.id);
holder.genre_title.setText(genre.genre);
perAnimes = new ArrayList<>();
DatabaseReference databaseAnime = FirebaseDatabase.getInstance().getReference("anime");
Query query_anime = databaseAnime.orderByChild("genreid").equalTo(genre.id);
query_anime.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
perAnimes.clear();
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Anime anime = snapshot.getValue(Anime.class);
perAnimes.add(anime);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
perAnimes.sort(new Comparator<Anime>() {
#Override
public int compare(Anime compare1, Anime compare2) {
return compare1.getTitle().compareToIgnoreCase(compare2.getTitle());
}
});
}
adapterPerAnime.notifyDataSetChanged();
} else {
perAnimes.clear();
adapterPerAnime.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
rvPerAnime = holder.itemView.findViewById(R.id.rvanime);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rvPerAnime.setLayoutManager(linearLayoutManager);
rvPerAnime.setHasFixedSize(true);
adapterPerAnime = new AnimeInsideGenreAdapter(perAnimes, context);
rvPerAnime.setAdapter(adapterPerAnime);
Animation up_from_bottom = AnimationUtils.loadAnimation(context, R.anim.up_from_bottom);
holder.itemView.startAnimation(up_from_bottom);
}
public int getItemCount() {
return this.genreList.size();
}
}
item_genre.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.pixplicity.fontview.FontAppCompatTextView
android:id="#+id/genre_title"
style="#style/FontTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:singleLine="true"
android:text="Genre Anime"
android:textColor="#f59e24"
android:textSize="14dp"
android:textStyle="bold" />
<com.pixplicity.fontview.FontAppCompatTextView
android:id="#+id/genre_id"
style="#style/FontTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="ID Genre"
android:textColor="#7c7c7c"
android:textSize="12dp"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rvanime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />
</LinearLayout>
AnimeInsideGenreAdapter.class
public class AnimeInsideGenreAdapter extends RecyclerView.Adapter<AnimeInsideGenreAdapter.ViewHolder> {
List<Anime> perAnimes;
private Context context;
private Random mRandom = new Random();
class ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
public FontAppCompatTextView anime_id, anime_title;
public ImageView img_anime;
public LinearLayout main;
public ViewHolder(final View itemView) {
super(itemView);
main = itemView.findViewById(R.id.main_layout);
anime_id = itemView.findViewById(R.id.anime_id);
anime_title = itemView.findViewById(R.id.anime_title);
img_anime = itemView.findViewById(R.id.img_anime);
Animation up_from_bottom = AnimationUtils.loadAnimation(itemView.getContext(), R.anim.up_from_bottom);
itemView.startAnimation(up_from_bottom);
}
}
public AnimeInsideGenreAdapter(List<Anime> perAnimes, Context context) {
this.perAnimes = perAnimes;
this.context = context;
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_anime_inside_genre, parent, false));
}
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Anime perAnime = this.perAnimes.get(position);
holder.anime_id.setText(perAnime.getId());
holder.anime_title.setText(perAnime.getTitle());
Toast.makeText(context, perAnime.toString(), Toast.LENGTH_SHORT).show();
Picasso.with(context).load(perAnime.getImgcover()).fit().into(holder.img_anime);
holder.img_anime.getLayoutParams().width = getRandomIntInRange(270,200);
holder.img_anime.getLayoutParams().height = 250;
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
}
});
}
public int getItemCount() {
return this.perAnimes.size();
}
// Custom method to get a random number between a range
protected int getRandomIntInRange(int max, int min){
return mRandom.nextInt((max-min)+min)+min;
}
}
item_anime_inside_genre.xml
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<com.pixplicity.fontview.FontAppCompatTextView
android:id="#+id/anime_id"
style="#style/FontTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:singleLine="true"
android:text="Anime ID"
android:textColor="#f59e24"
android:textSize="14dp"
android:textStyle="bold" />
<ImageView
android:id="#+id/img_anime"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"/>
<com.pixplicity.fontview.FontAppCompatTextView
android:id="#+id/anime_title"
style="#style/FontTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Anime Title"
android:textColor="#7c7c7c"
android:textSize="12dp" />
</LinearLayout>
</android.support.v7.widget.CardView>
Genre.class
public class Genre {
String id;
String genre;
public Genre() {
}
public Genre(String id, String genre) {
this.id = id;
this.genre = genre;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}}
Anime.class
public class Anime {
String id;
String genreid;
String title;
String description;
String imgcover;
public Anime() {
}
public Anime(String id, String genreid, String title, String description, String imgcover) {
this.id = id;
this.genreid = genreid;
this.title = title;
this.description = description;
this.imgcover = imgcover;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGenreid() {
return genreid;
}
public void setGenreid(String genreid) {
this.genreid = genreid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImgcover() {
return imgcover;
}
public void setImgcover(String imgcover) {
this.imgcover = imgcover;
}}
I need to show the anime list from Firebase inside each genres adapter.
Any help will be much appreciated.
Thank you.