Android fragments and adapter - android

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 .

Related

Recycler View leaving huge space before printing next card view

I'm trying to show all the card views using recycler view in main activity. Although I did not set a huge margin between card views, my recycler view shows a huge space to print the next card view. please see my attached image, you'll understand what I'm trying to say. I've attached all the code here. Can you please advise how to solve this problem? Thank you.
<?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/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:listitem="#layout/note_card" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:layout_marginRight="50dp"
android:layout_marginBottom="50dp"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="#+id/recyclerView"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="#drawable/add" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="7dp"
app:cardBackgroundColor="#color/green"
app:cardCornerRadius="5dp"
app:cardElevation="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textViewTitleCard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="TextView"
android:textSize="20sp" />
<TextView
android:id="#+id/textViewDescriptionCard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginTop="16dp"
android:text="TextView"
android:textSize="16sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.destructivepaul.quicknote;
import android.content.Context;
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.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder>{
private List<MyNote> myNoteList = new ArrayList<>();
// private Context context;
public void setMyNoteList(List<MyNote> myNoteList) {
this.myNoteList = myNoteList;
notifyDataSetChanged();
Log.i("info","note updated on adapter. note list size: "+myNoteList.size());
}
//public void setContext(Context context) {
// this.context = context;
// notifyDataSetChanged();
// Log.i("info","context updated on adapter");
// }
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.note_card
,parent,false);
return new NoteHolder(view);
}
#Override
public void onBindViewHolder(#NonNull NoteHolder holder, int position) {
MyNote myNote=myNoteList.get(position);
holder.textViewTitle.setText(myNote.getNote_title());
holder.textViewDescription.setText(myNote.getNote_description());
}
#Override
public int getItemCount() {
return myNoteList.size();
}
public class NoteHolder extends RecyclerView.ViewHolder{
private TextView textViewTitle, textViewDescription;
private CardView cardView;
public NoteHolder(#NonNull View itemView) {
super(itemView);
textViewTitle=itemView.findViewById(R.id.textViewTitleCard);
textViewDescription=itemView.findViewById(R.id.textViewDescriptionCard);
cardView=itemView.findViewById(R.id.cardView);
Log.i("info","card design found on adapter");
}
}
}
package com.destructivepaul.quicknote;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private FloatingActionButton fab;
private RecyclerView recyclerView;
private MyNoteViewModel myNoteViewModel;
private ActivityResultLauncher<Intent> activityResultLauncherForAddNote;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//resisterActivity
resisterActivityForAddNote();
fab=findViewById(R.id.fab);
recyclerView=findViewById(R.id.recyclerView);
NoteAdapter adapter=new NoteAdapter();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
Log.i("info","set the adapter");
myNoteViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication())
.create(MyNoteViewModel.class);
myNoteViewModel.getAllNotes().observe(MainActivity.this, new Observer<List<MyNote>>() {
#Override
public void onChanged(List<MyNote> myNotes) {
adapter.setMyNoteList(myNotes);
Log.i("info","adapter is called to update data");
}
});
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent =new Intent(MainActivity.this,CreateNoteActivity.class);
//resister activity launcher
activityResultLauncherForAddNote.launch(intent);
Log.i("info","called resister activity launcher on fab");
}
});
}
public void resisterActivityForAddNote(){
activityResultLauncherForAddNote=registerForActivityResult(new ActivityResultContracts.StartActivityForResult()
, new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
int resultCode=result.getResultCode();
Intent data = result.getData();
if (resultCode==RESULT_OK && data !=null) {
String title = data.getStringExtra("title");
String description = data.getStringExtra("description");
String colorName = data.getStringExtra("color");
MyNote myNote = new MyNote(title, description, colorName);
Log.i("info", "new note created on activity result");
myNoteViewModel.insert(myNote);
Log.i("info", "note saved to database");
}
}
});
}
}
I've solved my problem by myself. The problem was on card layout design(parent layout height should be wrap content instead of match parent).

RecyclerView onCreateViewHolder and onBindViewHolder not getting called

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.

Data not fetching in card view while retrieving data from firebase

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();
}

I add SearchView in Toolbar and Using Tab Layout in The Activity and I want SearchView to work in both Fragment that I added as Tab

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.

how to call RecyclerView in the first fragment of the navigation drawer? I've followed a tutorial by slidenerd but getting one error

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.

Categories

Resources