I am trying to fetch database from firebase but i cant get any text in cardview. Below is the xml file of card view.
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/colorAccent"
>
<TextView
android:id="#+id/viewname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Name"
android:textColor="#F44336"
android:textSize="132dp" />
<TextView
android:id="#+id/viewgenere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Genre"
android:textSize="32sp" />
</LinearLayout>
Below is the activity file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ViewUser">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerview"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Below is the activity file
package com.example.firebasedatabase;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.view.ViewGroup;
import com.example.firebasedatabase.Adapter.UserAdapter;
import com.example.firebasedatabase.Model.Showuser;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class ViewUser extends AppCompatActivity {
private RecyclerView recyclerView;
private DatabaseReference userdatabase;
UserAdapter userAdapter;
private List<Showuser>listData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_user);
recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
listData=new ArrayList<>();
userdatabase= FirebaseDatabase.getInstance().getReference("users");
userdatabase.keepSynced(true);
userdatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
for (DataSnapshot npsnapshot : dataSnapshot.getChildren()){
Showuser showuser=npsnapshot.getValue(Showuser.class);
listData.add(showuser);
}
userAdapter=new UserAdapter(listData);
recyclerView.setAdapter(userAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Below is the recycleradapter
package com.example.firebasedatabase.Adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.firebasedatabase.Model.Showuser;
import com.example.firebasedatabase.R;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import java.util.List;
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder>{
Context context;
private List<Showuser>listData;
public UserAdapter(Context context,List<Showuser>listData)
{
this.context=context;
this.listData=listData;
}
public UserAdapter(List<Showuser> listData) {
}
//
//
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.usercard,parent,false);
// return new ViewHolder(view) {
//
// };
return new ViewHolder(LayoutInflater.from(context)
.inflate(R.layout.usercard,parent,false));
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.txtuser.setText(new StringBuilder(listData.get(position).getShowuserName()));
holder.txtgenre.setText(new StringBuilder(listData.get(position).getShowuserGenre()));
}
#Override
public int getItemCount() {
return listData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView txtuser,txtgenre;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txtuser=(TextView)itemView.findViewById(R.id.viewname);
txtgenre=(TextView)itemView.findViewById(R.id.viewgenere);
}
}
}
I cannot view any text coming from firebase database.The firebase database rules are true.The view is created; just as i enter 4 data in firebase then it shows 4 card view but no text is shown and there is space between 1 card & 2 card near about 4 blank rows.
please help me out
I see the issue.
userAdapter=new UserAdapter(listData);
recyclerView.setAdapter(userAdapter);
Here you are initializing your UserAdapter. Notice that you are calling the wrong constructor or perhaps you have not implemented it.
// You should call this instead
public UserAdapter(Context context,List<Showuser>listData)
{
this.context=context;
this.listData=listData;
}
// You are calling this empty constructor
public UserAdapter(List<Showuser> listData) {
}
You should initialize your adapter like below.
userAdapter=new UserAdapter(ViewUser.this, listData);
You miss setting the list in adapter constructor, so change below
public UserAdapter(List<Showuser> listData) {
}
With
public UserAdapter(List<Showuser> listData) {
this.listData=listData;
}
Also, the list might be null, so change the return value of getItemCount()
#Override
public int getItemCount() {
return listData.size();
}
with
#Override
public int getItemCount() {
return listData == null? 0: listData.size();
}
Related
I am trying to create a dynamic list view by getting data from SQLite Database.
I created breakpoints and found out that onCreateViewHolder and onBindViewHolder of adapter files are not getting called. Anyway while trying to print the count within getItemCount(), I am getting the correct count. Could anyone please help me fix it?
List View.java
package com.hacker.wanderlust;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import com.hacker.wanderlust.adapter.TravelListAdapter;
import com.hacker.wanderlust.bean.Travel;
import com.hacker.wanderlust.dao.TravelDAO;
import com.hacker.wanderlust.logic.Conversion;
import java.text.ParseException;
import java.util.ArrayList;
public class TravelViewList extends AppCompatActivity {
TravelDAO travelDAO = new TravelDAO(this);
Conversion conversion = new Conversion();
ArrayList<Travel> travels=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_travel_view_list);
try {
RecyclerView travelList = (RecyclerView) findViewById(R.id.travelListView);
travelList.setLayoutManager(new LinearLayoutManager(this));
travelList.setHasFixedSize(true);
Cursor cursor = travelDAO.getTravelData();
Log.d("message","Cursor got data");
if(cursor!=null && cursor.getCount()>0) {
if(cursor.moveToFirst()) {
do {
Travel travel = new Travel();
travel.setName(cursor.getString(0));
travel.setLocation(cursor.getString(1));
travel.setDateOfTravel(conversion.toSQLDate(cursor.getString(2)));
Log.d("message",travel.getName());
travels.add(travel);
} while(cursor.moveToNext());
}
}
travelList.setAdapter(new TravelListAdapter(conversion.travelArrayListToArray(travels)));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Adapter File
package com.hacker.wanderlust.adapter;
import android.util.Log;
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.hacker.wanderlust.R;
import com.hacker.wanderlust.bean.Travel;
public class TravelListAdapter extends RecyclerView.Adapter<TravelListAdapter.TravelViewHolder> {
private Travel[] data;
public TravelListAdapter(Travel[] data) {
this.data = data;
}
#NonNull
#Override
public TravelViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d("message","onCreate");
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.travel_view, parent, false);
return new TravelViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull TravelViewHolder holder, int position) {
Travel travel=data[position];
holder.tripName.setText(travel.getName());
holder.tripDetails.setText(travel.getLocation());
}
#Override
public int getItemCount() {
Log.d("message","count: "+data.length);
return data.length;
}
public class TravelViewHolder extends RecyclerView.ViewHolder {
TextView tripName, tripDetails;
public TravelViewHolder(#NonNull View itemView) {
super(itemView);
tripName = itemView.findViewById(R.id.tripName);
tripDetails = itemView.findViewById(R.id.tripDetails);
}
}
}
travel_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingTop="10dp">
<TextView
android:id="#+id/tripName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textSize="34sp"></TextView>
<TextView
android:id="#+id/tripDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textSize="16sp"></TextView>
</LinearLayout>
activity_travel_view_list.xml
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/travelListView"
android:visibility="visible">
</androidx.recyclerview.widget.RecyclerView>
Dropbox link to entire project code: https://www.dropbox.com/s/5qs7ixiylrxzv41/Wanderlust.zip?dl=0
I tested the code(changed the part of getting data from DB) on my side, it works fine. My code:
public class TestRecyclerview02 extends AppCompatActivity {
ArrayList<Travel> travels=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_recycleview02);
try {
RecyclerView travelList = (RecyclerView) findViewById(R.id.travelListView);
travelList.setLayoutManager(new LinearLayoutManager(this));
travelList.setHasFixedSize(true);
// debug mock, not using the cursor.
travels.add(new Travel("AAAA", "123"));
travels.add(new Travel("BBBB", "1234"));
travels.add(new Travel("CCCC", "123456"));
travels.add(new Travel("DDDD", "1234567"));
travels.add(new Travel("EEEE", "1234567"));
travels.add(new Travel("FFFF", "12345678"));
travelList.setAdapter(new TravelListAdapter( travels.toArray(new Travel[0])));
} catch (Exception e) {
e.printStackTrace();
}
}
}
About the Adapter, I didn't change it, just added one line log in the method of onBindViewHolder
Log.d("message","onBindViewHolder");
Regards the travel_view.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" // ===> pay attention to this
android:orientation="vertical">
<TextView
android:id="#+id/tripName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tripName" />
<TextView
android:id="#+id/tripDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tripDetails" />
</LinearLayout>
And the result is ok.
The issue is that you are trying to access DB from the main thread. Your adapter is fine.
The issue was that in the recycler view (activity_travel_view_list.xml) the height and width were set to 0dp. I changed it to android:layout_width="match_parent" & android:layout_height="match_parent" and it worked. Thank you all for your contributions.
I'm trying to use a Searchview with Recylerview and firebase database, i've been following some tutorial and i've followed the video correctly so I don't know why i'm getting an error,i have three classn one is an adapater and a helper and the main one, the error i get is:
2021-05-12 03:16:12.931 31658-31658/com.example.search E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.search, PID: 31658
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.search.Deal
in the following line:
list.add(ds.getValue(Deal.class));
this is my main activity:
package com.example.search;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Deal> list;
RecyclerView recyclerView;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ref = FirebaseDatabase.getInstance().getReference().child("medicines");
recyclerView = findViewById(R.id.rv);
searchView = findViewById(R.id.searchview);
}
#Override
protected void onStart() {
super.onStart();
if(ref != null){
ref.addValueEventListener(new ValueEventListener() {
#NonNull
#Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
for(DataSnapshot ds : snapshot.getChildren()){
list.add(ds.getValue(Deal.class));
}
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
if (searchView != null){
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
}
private void search(String str) {
if (!str.equals("")){
ArrayList<Deal>myList = new ArrayList<>();
for (Deal object : list){
if(object.getDisease().toLowerCase().contains(str.toLowerCase())){
myList.add(object);
}
}
AdapterClass adapterClass = new AdapterClass(myList);
recyclerView.setAdapter(adapterClass);
}
}
}
and this is my "helper" class which i called deal:
package com.example.search;
public class Deal {
private String disease, medication;
public Deal() {
}
public Deal(String disease, String medication) {
this.disease = disease;
this.medication = medication;
}
public String getDisease() {
return disease;
}
public void setDisease(String disease) {
this.disease = disease;
}
public String getMedication() {
return medication;
}
public void setMedication(String medication) {
this.medication = medication;
}
}
this is my adapater class:
package com.example.search;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.MyViewHolder> {
ArrayList<Deal> list;
public AdapterClass(ArrayList<Deal> list){
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_holder, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.disease.setText(list.get(position).getDisease());
holder.medicine.setText(list.get(position).getMedication());
}
#Override
public int getItemCount() {
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView disease, medicine;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
disease = itemView.findViewById(R.id.disease);
medicine = itemView.findViewById(R.id.medication);
}
}
}
and this is my main activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="#+id/searchview"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:padding="10dp"
android:layout_margin="5dp"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:autofillHints="Search here"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
</LinearLayout>
and my card view layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="5dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="#+id/disease"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textStyle="bold"
android:padding="10dp"
android:text="disease_name" />
<TextView
android:id="#+id/medication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="solution"
android:padding="10dp"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"
/>
</androidx.cardview.widget.CardView>
that's all there is to the whole app so i dont get why the app keeps crashing, this is what my firebase database looks like
{
"medicines" : {
"disease" : "maleria",
"medication" : "aspirin"
}
}
I was getting different exceptions before and I changed the rules in database and debugged the app and now I'm getting this error been stuck on it for two hours, Honestly no clue, I've already tried checking if I wrote things wrong and if the names I added in my helper(deal)class match with the ones in firebase etc., and they do so I don't know
Since your Deal class defines properties disease and mediation, there seems to be only one Deal object under medicines.
So with your current data, you shouldn't be using a loop over getChildren in the onDataChange, and simple do:
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
list = new ArrayList<>();
list.add(snapshot.getValue(Deal.class));
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
I am Using a Tab Layout with two fragments both have Recycler View and also added Search View in Tab Layout but here I am facing a problem, I want Search View to work on Both Fragment that I added As Tab but Search View is in another activity(Toolbar) and both fragments are different
Activity Having Tabs(LanguageChooser Activity)
package com.piyushjaiswal.lyricswala;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.google.android.material.tabs.TabLayout;
public class LanguageChooser extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_language_chooser);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
SectionPagerAdapter pagerAdapter = new SectionPagerAdapter(getSupportFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
ViewPager pager = findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(pager);
}
private class SectionPagerAdapter extends FragmentPagerAdapter {
public SectionPagerAdapter(#NonNull FragmentManager fm, int behaviour) {
super(fm,behaviour);
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new Hindi();
case 1:
return new Punjabi();
}
return null;
}
#Override
public int getCount() {
return 2;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position)
{
case 0: return getResources().getText(R.string.Hindi);
case 1:return getResources().getText(R.string.Punjabi);
}
return null;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.toolbar,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed() {
System.exit(1);
}
}
XML CODE OF LanguageChooserActivity
<?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"
android:orientation="vertical"
tools:context=".LanguageChooser">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/toolbar"
android:background="#color/colorAccent"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
app:elevation="0dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tabs"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:id="#+id/pager"
android:layout_height="match_parent" />
</LinearLayout>
My Toolbar having Search View
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_Search"
android:title="#string/search"
android:icon="#android:drawable/ic_menu_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.widget.SearchView"
/>
</menu>
XML code of first Tab(Fragment) named as Hindi
<?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"
android:orientation="vertical"
tools:context=".Hindi">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/progressbar"
android:visibility="visible"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Java Code of Tab(Fragment) named as Hindi
package com.piyushjaiswal.lyricswala;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.app.SearchManager;
import android.widget.ProgressBar;
import androidx.appcompat.widget.SearchView;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
/**
* A simple {#link Fragment} subclass.
*/
public class Hindi extends Fragment {
View v;
private RecyclerView myRecyclerview;
private List<Contact> listContact = new ArrayList<>();
private FirebaseDatabase database = FirebaseDatabase.getInstance();
private DatabaseReference myRef = database.getReference();
private RecyclerViewAdapter recyclerViewAdapter;
private ProgressBar progressBar;
public Hindi() {
// Required empty public constructor
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_hindi,container,false);
progressBar= v.findViewById(R.id.progressbar);
progressBar.setVisibility(View.VISIBLE);
myRecyclerview = v.findViewById(R.id.recyclerView);
myRecyclerview.setHasFixedSize(true);
myRecyclerview.setItemViewCacheSize(10);
recyclerViewAdapter = new RecyclerViewAdapter(getContext(),listContact);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
myRecyclerview.setLayoutManager(layoutManager);
myRecyclerview.setAdapter(recyclerViewAdapter);
return v;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myRef.child("Hindi").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
listContact.add(dataSnapshot1.getValue(Contact.class));
}
recyclerViewAdapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getActivity(),databaseError.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
Recycler View Adapter
package com.piyushjaiswal.lyricswala;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private Context mContext;
private List<Contact> mData;
private List<Contact> mDataFull;
public RecyclerViewAdapter(Context mContext, List<Contact> mData) {
this.mContext = mContext;
this.mData = mData;
mDataFull = new ArrayList<>(mData);
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(mContext).inflate(R.layout.item_songs,parent,false);
MyViewHolder vHolder= new MyViewHolder(v);
return vHolder;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.setData(mData.get(position).getName(),mData.get(position).getPhone(),mData.get(position).getUrl(),mData.get(position).getLyrics());
}
#Override
public int getItemCount() {
return mData.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder
{
private TextView tv_name;
private TextView tv_phone;
private ImageView imageView;
MyViewHolder(#NonNull View itemView) {
super(itemView);
tv_name = (TextView) itemView.findViewById(R.id.name_contact);
tv_phone = (TextView) itemView.findViewById(R.id.phone_contact);
imageView = (ImageView) itemView.findViewById(R.id.img_contact);
}
private void setData(final String name, final String phone, String url, final String Lyrics){
Glide.with(itemView.getContext()).load(url).into(imageView);
this.tv_phone.setText(phone);
this.tv_name.setText(name);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Intent intent = new Intent(itemView.getContext(),LyricsActivit.class);
intent.putExtra("Lyrics",Lyrics);
intent.putExtra("albumname",phone);
intent.putExtra("songname",name);
itemView.getContext().startActivity(intent);
}
});
}
}
}
Screen Shot of My ActivityApp Output
I want above toolbar search view to work on tabs(fragment) Hope I explain my problem
Create a view pager and tab layout together. it will be resolved.Here is an example.
I have the following code which is a fragment that has a recycler view and I have an adapter, debugging my code shows that the adapter is getting called after the fragment returns the result, although I am creating an instance of the adapter and setting it to the recycler view and setting the wanted results before returning the fragment. can someone help explaining what's happening I am new to Android with a bit of java experience.
Here is my fragment class:
package com.clowiz.ui.gallery;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.clowiz.MainActivity;
import com.clowiz.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
import static android.app.Activity.RESULT_OK;
public class GalleryFragment extends Fragment {
public static final int ADD_UNIVERSITY_CODE = 1;
private GalleryViewModel galleryViewModel;
private UniversityViewModel universityViewModel;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_gallery, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
FloatingActionButton buttonAddUniversity = view.findViewById(R.id.button_add_university);
buttonAddUniversity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), AddUniversityActivity.class);
startActivityForResult(intent, ADD_UNIVERSITY_CODE);
}
});
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
final UniversityAdapter adapter = new UniversityAdapter();
recyclerView.setAdapter(adapter);
universityViewModel = ViewModelProviders.of(this).get(UniversityViewModel.class);
universityViewModel.getAllUniversities().observe(this, new Observer<List<University>>() {
#Override
public void onChanged(#Nullable List<University> unis) {
adapter.setUniversities(unis);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == ADD_UNIVERSITY_CODE && resultCode == RESULT_OK) {
String name = data.getStringExtra(AddUniversityActivity.EXTRA_NAME);
University uni = new University(name);
universityViewModel.insert(uni);
Toast.makeText(getContext(), "uni added successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "uni not saved", Toast.LENGTH_SHORT).show();
}
}
}
Here is my adapter:
package com.clowiz.ui.gallery;
import android.util.Log;
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.clowiz.R;
import java.util.ArrayList;
import java.util.List;
public class UniversityAdapter extends RecyclerView.Adapter<UniversityAdapter.UniversityHolder> {
private List<University> universities = new ArrayList<>();
#NonNull
#Override
public UniversityHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.university_item, parent, false);
return new UniversityHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull UniversityHolder holder, int position) {
University university = universities.get(position);
holder.textViewId.setText(String.valueOf(university.getId()));
holder.textViewName.setText(university.getName());
}
#Override
public int getItemCount() {
return universities.size();
}
public void setUniversities(List<University> universities) {
this.universities = universities;
notifyDataSetChanged();
}
class UniversityHolder extends RecyclerView.ViewHolder {
private TextView textViewId;
private TextView textViewName;
public UniversityHolder(View itemView) {
super(itemView);
textViewId = itemView.findViewById(R.id.text_view_id);
textViewName = itemView.findViewById(R.id.text_view_name);
}
}
}
Here is my viewModel:
package com.clowiz.ui.gallery;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class UniversityViewModel extends AndroidViewModel {
private UniversityRepository repository;
private LiveData<List<University>> allUniversities;
public UniversityViewModel(#NonNull Application application) {
super(application);
repository = new UniversityRepository(application);
allUniversities = repository.getAllUniversities();
}
public void insert(University university) {
repository.insert(university);
}
public void update(University university) {
repository.update(university);
}
public void delete(University university) {
repository.delete(university);
}
public LiveData<List<University>> getAllUniversities() {
return allUniversities;
}
}
Here is my listItem:
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.023">
<TextView
android:id="#+id/text_view_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="Id"
android:textAppearance="#style/TextAppearance.AppCompat.Large"></TextView>
<TextView
android:id="#+id/text_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_toStartOf="#id/text_view_id"
android:layout_toLeftOf="#id/text_view_id"
android:text="Name"
android:textAppearance="#style/TextAppearance.AppCompat.Large"></TextView>
</RelativeLayout>
</LinearLayout>
Here is my fragment view:
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="159dp"
tools:layout_editor_absoluteY="182dp"
tools:listitem="#layout/university_item">
</androidx.recyclerview.widget.RecyclerView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/button_add_university"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_add_black_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.21"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.916" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is my repository:
package com.clowiz.ui.gallery;
public class UniversityViewModel extends AndroidViewModel {
private UniversityRepository repository;
private LiveData<List<University>> allUniversities;
public UniversityViewModel(#NonNull Application application) {
super(application);
repository = new UniversityRepository(application);
allUniversities = repository.getAllUniversities();
}
public void insert(University university) {
repository.insert(university);
}
public void update(University university) {
repository.update(university);
}
public void delete(University university) {
repository.delete(university);
}
public LiveData<List<University>> getAllUniversities() {
return allUniversities;
}
}
If you want to have the correct design around this, you should move all that code to onViewCreated instead and keep onCreateView as simple as:
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_gallery, container, false);
}
Edit: Also, provide a LayoutManager to the RecyclerView as I've missed that on my initial read.
And then you can use the view instance of onViewCreated to get your other views.
your problem is that once you open a fragment, a list of uni's is displayed by default. when you click on add a new uni using the floating button, you go to 'AddUniversityActivity' and expect when you get back to see the new one added with no duplicates or weird behaviour.
here is what I think you should do :
1) override|impelment hashcode on the class University to make each instance unique ( maybe use university id ).
2) use HashSet as a collection for your universities instead of List.
since you are learning, take a look at observable design pattern , activity lifecycle , fragmnet lifecycle .
This is the Java file of the fragment I wish to insert recycler view. Please dont worry about the package name which I deleted for some reasons.
import android.app.Activity;
import android.os.Bundle;
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 java.util.ArrayList;
import java.util.List;
public class Dashboard extends Fragment {
private RecyclerView recyclerView;
private RecyclerAdapter adapter;
/**
* Returns a new instance of this fragment for the given section number.
*/
public static Dashboard newInstance() {
Dashboard fragment = new Dashboard();
return fragment;
}
public Dashboard () {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_dashboard, container,
false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.drawerlist);
adapter=new RecyclerAdapter(getActivity().getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return rootView;
}
public static List<Information> getData(){
List<Information> data=new ArrayList<>();
String[] titles={"Rooms Occupied","RoomsVacant","Check-In","Check-Out","Extensions","Confirmations","Cancellations"};
for(int i=0;i<titles.length;i++)
{
Information current =new Information();
current.title=titles[i];
data.add(current);
}
return data;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
}
This is my Adapter class
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Collections;
import java.util.List;
/**
* Created by gowtham on 6/13/2015.
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private LayoutInflater inflater;
List<Information> data= Collections.emptyList();
public RecyclerAdapter(Context context, List<Information> data){
inflater=LayoutInflater.from(context);
this.data=data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.custom_row, parent,false);
MyViewHolder holder=new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Information current=data.get(position);
holder.title.setText(current.title);
}
#Override
public int getItemCount() {
return 0;
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView title;
public MyViewHolder(View itemView) {
super(itemView);
title= (TextView) itemView.findViewById(R.id.viewText);
}
}
}
This is Layout file of the fragment in which I want to use the recycler view
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/viewImage"
android:background="#drawable/ic_dashboard"
android:layout_gravity="center_vertical"
android:gravity="center"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/viewText"
android:text="Dummy Text"
android:textStyle="bold"
android:layout_gravity="left"
android:gravity="center" />
</LinearLayout>
Since I'm new to stackoverflow I don't have enough reputations to add image. So I will attach the screenshot in the comments below. Please take a look at it to know what is happening here exactly. Thanks!
Why you call getActivity().getData(), just call getData().
And in your Adapter class:
#Override
public int getItemCount() {
return data.size();
}
It can't just return zero, you should return the data size.