particular title(fetched from api) using searchview? - android

I want something like this:
so the thing is, what I exactly want is when user type particular topic name(if present in-app) in searchview it should able give suggestions and if found it should open that topic activity (just like Facebook, Instagram,...etc searches)..and those title are coming from API(which I have successfully displayed in other activities)..like this:
..what will the logic for it??? need help... Thanks
so I have just included searchview in XML like this-->
<SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="#drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="#style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"
/>
Need help..thanks in advance....
here is my json:
[{"id":"11","title":"TextView"},{"id":"10","title":"Edit Text"},{"id":"9","title":"ImageView"},{"id":"8","title":"Button "},{"id":"7","title":"CheckBox"},{"id":"6","title":"RadioButton & RadioGroup"},{"id":"5","title":"DatePicker"},{"id":"4","title":"TimePicker"},{"id":"3","title":"Switch"},{"id":"1","title":"Simple & Custom Toast"}]
here is my activity: for
public class StartLearning extends AppCompatActivity {
private RecyclerView recyclerView;
private SLAdapter slAdapter;
ProgressDialog progressDialog;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startlearning_layout);
progressDialog = new ProgressDialog(StartLearning.this);
progressDialog.setMessage("Loading....");
progressDialog.show();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
/*Create handle for the RetrofitInstance interface*/
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
Call<List<SlModel>> call = service.getMySlmodel();
call.enqueue(new Callback<List<SlModel>>() {
#Override
public void onResponse(Call<List<SlModel>> call, Response<List<SlModel>> response) {
progressDialog.dismiss();
generateDataList(response.body());
Log.e("hello", String.valueOf(response.body()));
}
#Override
public void onFailure(Call<List<SlModel>> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
}
private void generateDataList(List<SlModel> employeeList) {
recyclerView = findViewById(R.id.SLrecycle);
LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
slAdapter = new SLAdapter(getApplicationContext(),employeeList);
recyclerView.setAdapter(slAdapter);
}
adapter:
public class SLAdapter extends RecyclerView.Adapter<SLAdapter.CustomViewHolder> {
List<StartLearning.SlModel> Slmdel;
Context context;
public SLAdapter(Context context,List<StartLearning.SlModel> employees) {
this.Slmdel = employees;
this.context=context;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.startlearning_item, parent, false);
return new CustomViewHolder(itemView);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// TipsModel employee = employees.get(position);
//// holder.employeeName.setText(employees.get(position).getTips());
holder.textView.setText(String.valueOf(position+1)+". ");
holder.employeeName.setText(Slmdel.get(position).getTitle());
}
#Override
public int getItemCount() {
return Slmdel.size();
//return (employees == null) ? 0 : employees.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.Sl2);
textView=view.findViewById(R.id.Sl1);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, NextSLactivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title", Slmdel.get(getAdapterPosition()).getTitle());
intent.putExtra("idSLnext", Slmdel.get(getAdapterPosition()).getId());
//Log.e("ashwini",WAmdel.get(getAdapterPosition()).getId());
context.startActivity(intent);
}
});
}
}
onclick of item(example :textview)
activity:one of the items(example :textview)
public class JavaFragment extends Fragment {
private RecyclerView recyclerView;
private NextSLJavaAdapter adapter;
private NextSLModel DescriptList;
ProgressDialog progressDialog;
public JavaFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.nextsl_layout, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Toolbar toolbar = (Toolbar) getView().findViewById(R.id. toolbar );
// setSupportActionBar( toolbar );
//if (getSupportActionBar() != null) {
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// getSupportActionBar().setDisplayShowHomeEnabled(true);
//}
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Loading....");
progressDialog.show();
Intent intent = getActivity().getIntent();
String title = intent.getStringExtra("title");
//getSupportActionBar().setTitle(title);
String id = intent.getStringExtra("idSLnext");
Log.e("ashwini", String.valueOf(id));
/*Create handle for the RetrofitInstance interface*/
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
Call<NextSLModel> call = service.getnextslmodel(id);
call.enqueue(new Callback<NextSLModel>() {
#Override
public void onResponse(Call<NextSLModel> call, Response<NextSLModel> response) {
progressDialog.dismiss();
DescriptList=response.body();
generateDataList(DescriptList);
}
#Override
public void onFailure(Call<NextSLModel> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(getContext(), "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
private void generateDataList(NextSLModel photoList) {
recyclerView = getView().findViewById(R.id.nextSLrecycle);
LinearLayoutManager manager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
adapter = new NextSLJavaAdapter(getContext(),photoList);
recyclerView.setAdapter(adapter);
}
}
adapter:
public class NextSLJavaAdapter extends RecyclerView.Adapter<NextSLJavaAdapter.CustomViewHolder> {
NextSLModel Slmdel;
Context context;
public NextSLJavaAdapter(Context context, NextSLModel employees) {
this.Slmdel = employees;
this.context = context;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.nextsl_item, parent, false);
return new CustomViewHolder(itemView);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// TipsModel employee = employees.get(position);
//// holder.employeeName.setText(employees.get(position).getTips());
///////// holder.textView.setText(String.valueOf(position + 1) + ". ");
holder.employeeName.setText(Slmdel.getJava());
Log.e("sl",Slmdel.getJava());
}
#Override
public int getItemCount() {
return 1;
//return (employees == null) ? 0 : employees.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.detailsStartLearning);
textView = view.findViewById(R.id.Sl1);}}}
look at this search activity:
public class Search extends AppCompatActivity {
SearchView searchView;
RecyclerView recyclerView;
SearchAdapter slAdapter;
List<StartLearning.SlModel> movieList;
ChipGroup chipGroup;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
searchView=findViewById(R.id.searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
searchForResults(newText);
return false;
}
});
//new code
chipGroup = findViewById(R.id. chipGroup);
searchView.onActionViewExpanded();
searchView.setIconified(true);
}
public void searchForResults(String search){
//here make an api call to get the results, complete the code here
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
retrofit2.Call<List<StartLearning.SlModel>> call = service.getMySlmodel();
call.enqueue(new Callback<List<StartLearning.SlModel>>() {
#Override
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
List<StartLearning.SlModel> list = response.body();
generateDataList(list);
addChips(list);
Log.d("TAG","Response = "+movieList);
slAdapter.setMovieList(getApplicationContext(),movieList);
}
#Override
public void onFailure(retrofit2.Call<List<StartLearning.SlModel>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
}
});
}
private void generateDataList(List<StartLearning.SlModel> employeeList) {
recyclerView = findViewById(R.id.recyclerview);
LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
slAdapter = new SearchAdapter(getApplicationContext(),employeeList);
recyclerView.setAdapter(slAdapter);
}
public void addChips(List<StartLearning.SlModel> searchItems){
for (StartLearning.SlModel item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chips, null, false);
mChip.setText(item.getTitle());
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.removeAllViews();
chipGroup.addView(mChip);
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
}
xml of search:
<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="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" >
</androidx.appcompat.widget.Toolbar>
<SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="#drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="#style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="#+id/chipGroup"
app:chipSpacing="25dp"/>
</LinearLayout>
Search adapter :
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.CustomViewHolder> implements Filterable {
List<StartLearning.SlModel> Slmdel;
List<StartLearning.SlModel> Slmdel1;
Context context;
public SearchAdapter() {
}
public void setMovieList(Context context, final List<StartLearning.SlModel> movieList){
this.context = context;
if(this.Slmdel == null){
this.Slmdel = movieList;
this.Slmdel1 = movieList;
notifyItemChanged(0, Slmdel1.size());
} else {
final DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
#Override
public int getOldListSize() {
return SearchAdapter.this.Slmdel.size();
}
#Override
public int getNewListSize() {
// return movieList.size();
return (movieList == null) ? 0 : movieList.size();
}
#Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return SearchAdapter.this.Slmdel.get(oldItemPosition).getTitle() == movieList.get(newItemPosition).getTitle();
}
#Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
StartLearning.SlModel newMovie = SearchAdapter.this.Slmdel.get(oldItemPosition);
StartLearning.SlModel oldMovie = movieList.get(newItemPosition);
return newMovie.getTitle() == oldMovie.getTitle() ;
}
});
this.Slmdel = movieList;
this.Slmdel1 = movieList;
result.dispatchUpdatesTo(this);
}
}
public SearchAdapter(Context context,List<StartLearning.SlModel> employees) {
this.Slmdel = employees;
this.context=context;
}
#Override
public SearchAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.startlearning_item, parent, false);
return new SearchAdapter.CustomViewHolder(itemView);
}
#Override
public void onBindViewHolder(SearchAdapter.CustomViewHolder holder, int position) {
holder.employeeName.setText(Slmdel.get(position).getTitle());
}
#Override
public int getItemCount() {
if(Slmdel != null){
return Slmdel1.size();
} else {
return 0;
}
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final List<StartLearning.SlModel> results = new ArrayList<StartLearning.SlModel>();
if (Slmdel1 == null)
Slmdel1 = Slmdel;
if (constraint != null) {
if (Slmdel1 != null & Slmdel1.size() > 0) {
for (final StartLearning.SlModel g : Slmdel1) {
if (g.getTitle().toLowerCase().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Slmdel1 = (ArrayList<StartLearning.SlModel>) results.values;
notifyDataSetChanged();
}
};}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.Sl2);
textView = view.findViewById(R.id.Sl1);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, NextSLactivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title", Slmdel.get(getAdapterPosition()).getTitle());
intent.putExtra("idSLnext", Slmdel.get(getAdapterPosition()).getId());
//Log.e("ashwini",WAmdel.get(getAdapterPosition()).getId());
context.startActivity(intent);
}
});
}
}
}

You can achieve suggestions related to your search query using recyclerview and adapters.
[1] Create new adapter and put your setMovieList() and getFilter() into it.
[2] Set that adapter into recyclerview of suggestions and notify adapter when you get your arraylist of suggestions.
check below code
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
movieList = response.body();
if(movieList.size()!=0){
tvSuggestions.setVisibility(View.VISIBLE);
suggestionAdapter=new SuggestionAdapter(Search.this,movieList);
recyclerViewSuggestions.setAdapter(suggestionAdapter);
Log.e("TAG", "onResponse: size of movielist "+movieList);
suggestionAdapter.getFilter().filter(query);
suggestionAdapter.notifyDataSetChanged();
suggestionAdapter.setMovieList(Search.this,movieList);
}
else{
tvSuggestions.setVisibility(View.VISIBLE);
tvSuggestions.setText("No Suggestions Found");
}
/*generateDataList(movieList);
Log.d("TAG","Response = "+movieList);
slAdapter.setMovieList(getApplicationContext(),movieList);*/
}

There is a new Chip Material Component in android. Which can be used to fullfill the requirements. I belive you are currently using some recyclerview to display those search items instead of using this use ChiGroup to hold those values.a
Below is some sample code to do
First add this to your gradle for using the external libarary dependency
implementation 'com.google.android.material:material:1.0.0-alpha1'
Then in your desired layout below the search view place this xml code.
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="#+id/chipGroup"
app:chipSpacing="25dp"/>
The ChipGroup will hold the Chip items which will be added dynamically.
So now in your search activity/fragment just get a reference of this layout group.
public class Search extends AppCompatActivity {
SearchView searchView;
ChipGroup chipGroup;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
searchView = findViewById(R.id.searchView);
//new code
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
searchForResults(newText);
return false;
}
});
//new code
chipGroup = findViewById(R.id. chipGroup);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() ==android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
//new code
public void searchForResults(String search){
//here make an api call to get the results, complete the code here
call.enqueue(new Callback<List<StartLearning.SlModel>>() {
#Override
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
List<StartLearning.SlModel> list = response.body();
//after getting the results pass to addChips()
addChips(list)
Log.d("TAG","Response = "+movieList);
}
#Override
public void onFailure(retrofit2.Call<List<StartLearning.SlModel>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
}
});
}
//just call this when you get the search result from the api with your custom model and where ever it is applicable.
public void addChips(List<StartLearning.SlModel> searchItems){
for (StartLearning.SlModel item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chip, null, false);
mChip.setText(item.title);
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.removeAllViews();
chipGroup.addView(mChip);
}
}
}
I can't find the relevant code in Search activity to give an example. but the general idea is as below.
1) You add a ChipGroup to hold the Chip Views which will be added dynamically in your search view xml.
2) User Search something and you get the api response and you create a model based list.
3) you then iterate over the list one by one and create the dynamic chips.
4) But first create an item_chip.xml file with below content.
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:id=#+id/smallChip
style="#style/Widget.MaterialComponents.Chip.Choice"
android:textAppearance="?android:attr/textAppearance"
android:textColor="#color/secondaryTextColor"
app:chipBackgroundColor="#color/colorAccent" />
5) Now we are going to just inflate this layout file and add this to ChipGroup in for loop which we received earlier.
6) so the sample code goes like this to add the dynamic chips to ChipGroup. Here im using String as search items for simplicity you can use your own model here.
public void addChips(ArrayList<String> searchItems){
for (String item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chip, null, false);
mChip.setText(item);
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.addView(mChip);
}
}
now we have just added the chips dynamically to chipGroup which we declared earlier in search view layout . But this can also be done using Recyclerview instead of using ChipGropup just add the Chip View inside the recyclerview items and get a reference and set the text as you do with text views nothing to change except in adapter and item layout.
Edit: 4/1/20
Place the ChipGrop into the below XML file with search view. The idea is that the search view input box will be on top and the suggestions from the search will be just below the search box to give changing search results just right there on same screen. so call the search-related API call in the Search activity itself and pass the results to the sample method addChips() I have mentioned above.
<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="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="#drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="#style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"/>
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="#+id/chipGroup"
app:chipSpacing="25dp"/>
</LinearLayout>
For more info read below blogs:
Material Design Chips
How to use Chips Blog
How to add Chips to ChipsGroup

Add this library in your gradle
implementation 'com.google.android.material:material:1.2.0-alpha02'
Change parent of AppTheme to Theme.MaterialComponents.Light.NoActionBar in values/styles.xml .just like this
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
Now You need to add edittext and chipgroup to your xml.Just like this
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/search_edittext"/>
<com.google.android.material.chip.ChipGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/chipgroup"
app:singleSelection="true"
>
</com.google.android.material.chip.ChipGroup>
Now create method add chip to chipgroup
void setChip(List<String> list)
{
chipgroup.removeAllViews();
for (String item : list)
{
Chip chip =new Chip(this);
chip.setText(item);
// necessary to get single selection working
chip.setCheckable(true);
chip.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("OnCheckedChangeListener", "Called");
}
});
//on chip click
chipgroup.addView(chip);
}
}
Now add addTextChangedListener to your edittext
search_edittext.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
List<String> tem=new ArrayList();
for (String item : list)
{
if (item.toString().toLowerCase().contains(s.toString().toLowerCase()))
tem.add(item);
}
setChip(tem);
}
});
And this done.

You can do this Chip View button you after spending little time i found this library will be more suitable in your case as you are trying to achieve with search view.
So Try this out :
Add this line to your module level build.gradle:
dependencies {
implementation "com.hootsuite.android:nachos:1.1.1"
}
Include a NachoTextView in your xml layout as follows:
<com.hootsuite.nachos.NachoTextView
android:id="#+id/nacho_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
You can look entire thing on github also as you want to achieve through search view look for this answer : SearchView query hint before clicking it

Related

How to update one recycler view content from another recycler view item click

I'm new to Android world, and stuck with one issue now. I tried a lot from past 3-4 days, but still couldn't fix the issue. With lots of hope I'm posting this question today here. Looking forward to hear from you.
In same activity, I've two recycler views. One at top (adapter name SubCategoryAdapterTop) and one at below full screen (adapter name SubCategoryAdapter). I'm passing one position (POS) to SubCategoryAdapterTop captured from previous main activity, and passing two positions to SubCategoryAdapter (POS, POS1 -default 1). May be if you look at my codes below, can understand it properly. Now I wish to click on each item on top recycler view and acoordingly want to pass the clicked position as POS1 to SubCategoryAdapter and regenerate/refresh the content of it. Example- if I click 2nd item in top recycler view, then POS1 should be 2 and passed on to SubCategoryAdapter along with earlier POS value and refresh it's content accordingly.
Please help me how to do that. Thanks in advance !
Activity with 2 recycler views:
SubCategoryAdapter Code:
public class SubCategoryAdapter extends RecyclerView.Adapter<SubCategoryAdapter.MainViewHolder> {
List<response_model_fetch_subcategory> data;
Context context;
public SubCategoryAdapter(List<response_model_fetch_subcategory> data, Context context) {
this.data = data;
this.context = context;
}
#NonNull
#Override
public SubCategoryAdapter.MainViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.subcategory_single, parent, false);
return new MainViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SubCategoryAdapter.MainViewHolder holder, int position) {
holder.subCategoryTextView1.setText(data.get(position).getPname());
holder.subCategoryTextView2.setText(data.get(position).getPbrand());
holder.subCategoryTextView3.setText(Integer.toString(data.get(position).getPquantity1()));
holder.subCategoryTextView4.setText(data.get(position).getPunit());
holder.subCategoryTextView5.setText(String.format("%.2f",Double.valueOf(data.get(position).getPcost1())));
holder.subCategoryTextView6.setText(String.format("%.2f",Double.valueOf(data.get(position).getPcost1())));
holder.subCategoryTextView7.setText(Integer.toString(data.get(position).getDiscountamount()));
Glide.with(holder.subCategoryImageView1.getContext()).load("http://10.0.2.2/localshop/localshopimages/product/"+data.get(position).getPimage1()).into(holder.subCategoryImageView1);
holder.subCardViewContainer1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, LoginVerifyOTP.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return data.size();
}
public class MainViewHolder extends RecyclerView.ViewHolder {
CardView subCardViewContainer1;
ImageView subCategoryImageView1;
TextView subCategoryTextView1, subCategoryTextView2, subCategoryTextView3, subCategoryTextView4, subCategoryTextView5, subCategoryTextView6, subCategoryTextView7;
Button subCategoryButton1;
public MainViewHolder(#NonNull View itemView) {
super(itemView);
subCardViewContainer1 = itemView.findViewById(R.id.subCardViewContainer1);
subCategoryImageView1 = itemView.findViewById(R.id.subCategoryImageView1);
subCategoryButton1 = itemView.findViewById(R.id.subCategoryButton1);
subCategoryTextView1 = itemView.findViewById(R.id.subCategoryTextView1);
subCategoryTextView2 = itemView.findViewById(R.id.subCategoryTextView2);
subCategoryTextView3 = itemView.findViewById(R.id.subCategoryTextView3);
subCategoryTextView4 = itemView.findViewById(R.id.subCategoryTextView4);
subCategoryTextView5 = itemView.findViewById(R.id.subCategoryTextView5);
subCategoryTextView6 = itemView.findViewById(R.id.subCategoryTextView6);
subCategoryTextView7 = itemView.findViewById(R.id.subCategoryTextView7);
}
}
}
SubCategoryAdapterTop Code:
public class SubCategoryAdapterTop extends RecyclerView.Adapter<SubCategoryAdapterTop.MainViewHolder> {
List<response_model_fetch_subcategoryTop> data1;
Context context;
int row_index = 0;
public SubCategoryAdapterTop(List<response_model_fetch_subcategoryTop> data1, Context context) {
this.data1 = data1;
this.context = context;
}
#NonNull
#Override
public SubCategoryAdapterTop.MainViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.subcategory_topsingle, parent, false);
return new SubCategoryAdapterTop.MainViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SubCategoryAdapterTop.MainViewHolder holder, #SuppressLint("RecyclerView") int position) {
holder.subCategoryTextViewTop1.setText(data1.get(position).getSubcategoryname());
holder.subCardViewContainerTop1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
row_index = position;
notifyDataSetChanged();
}
});
if (row_index == position) {
holder.subCardViewContainerTop1.setBackgroundResource(R.drawable.selected_item_bg);
}
else
{
holder.subCardViewContainerTop1.setBackgroundResource(R.drawable.unselected_item_bg);
}
}
#Override
public int getItemCount() {
return data1.size();
}
public class MainViewHolder extends RecyclerView.ViewHolder {
LinearLayoutCompat subCardViewContainerTop1;
TextView subCategoryTextViewTop1;
public MainViewHolder(#NonNull View itemView) {
super(itemView);
subCardViewContainerTop1 = itemView.findViewById(R.id.subCardViewContainerTop1);
subCategoryTextViewTop1 = itemView.findViewById(R.id.subCategoryTextViewTop1);
}
}
}
SubCategoryActivity Code:
public class SubCategoryActivity extends AppCompatActivity {
RecyclerView subRecyclerView, subRecyclerViewTop1;
SubCategoryAdapter adapter;
SubCategoryAdapterTop adapterTop;
String pos, pos1;
Intent intent;
#SuppressLint("MissingInflatedId")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub_category);
// recycler view code
subRecyclerView = findViewById(R.id.subRecyclerView);
subRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
subRecyclerViewTop1 = findViewById(R.id.subRecyclerViewTop1);
subRecyclerViewTop1.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false));
intent = getIntent();
pos = intent.getStringExtra("pos");
Log.d(TAG, "Checking for incoming intent extras: " + pos);
pos1 = Integer.toString(1);
Log.d(TAG, "Checking for incoming intent extras1: " + pos1);
fetchingProduct(pos, pos1);
fetchingProductTop(pos);
}
public void fetchingProduct(String pos, String pos1) {
Call<List<response_model_fetch_subcategory>> call = apicontroller
.getInstance()
.getApi()
.getSubCategoryData(pos, pos1);
call.enqueue(new Callback<List<response_model_fetch_subcategory>>() {
#Override
public void onResponse(#NonNull Call<List<response_model_fetch_subcategory>> call, #NonNull Response<List<response_model_fetch_subcategory>> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
List<response_model_fetch_subcategory> data = response.body();
adapter = new SubCategoryAdapter(data, getApplicationContext());
subRecyclerView.setAdapter(adapter);
}
}
}
#Override
public void onFailure(#NonNull Call<List<response_model_fetch_subcategory>> call, #NonNull Throwable t) {
Log.d(TAG, "Last_Error" + t.toString());
Toast.makeText(getApplicationContext(), t.toString(), Toast.LENGTH_LONG).show();
}
});
Log.d(TAG, "Checking for incoming intent extras_: " + pos);
Log.d(TAG, "Checking for incoming intent extras_1: " + pos1);
}
private void fetchingProductTop(String pos) {
Call<List<response_model_fetch_subcategoryTop>> call = apicontroller
.getInstance()
.getApi()
.getSubCategoryNames(pos);
call.enqueue(new Callback<List<response_model_fetch_subcategoryTop>>() {
#Override
public void onResponse(#NonNull Call<List<response_model_fetch_subcategoryTop>> call, #NonNull Response<List<response_model_fetch_subcategoryTop>> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
List<response_model_fetch_subcategoryTop> data1 = response.body();
adapterTop = new SubCategoryAdapterTop(data1, getApplicationContext());
subRecyclerViewTop1.setAdapter(adapterTop);
}
}
}
#Override
public void onFailure(#NonNull Call<List<response_model_fetch_subcategoryTop>> call, #NonNull Throwable t) {
Log.d(TAG, "Last_Error" + t.toString());
Toast.makeText(getApplicationContext(), t.toString(), Toast.LENGTH_LONG).show();
}
});
}
}
apiset coode:
public interface apiset {
#FormUrlEncoded
#POST("login_user.php")
Call<response_model_login_user> getRegister(
#Field("mobilenumber") String mobilenumber,
#Field("area") String area,
#Field("firstname") String firstname,
#Field("lastname") String lastname,
#Field("emailid") String emailid,
#Field("deliveryaddress") String deliveryaddress
);
#GET("fetch_category.php")
Call<List<response_model_fetch_category>> getData();
/*
#GET("fetch_subcategory.php")
Call<List<response_model_fetch_subcategory>> getSubCategoryData();
*/
#FormUrlEncoded
#POST("fetch_subcategory.php")
Call<List<response_model_fetch_subcategory>> getSubCategoryData(
#Field("pos") String pos,
#Field("pos1") String pos1
);
#FormUrlEncoded
#POST("fetch_subcategory_names.php")
Call<List<response_model_fetch_subcategoryTop>> getSubCategoryNames(
#Field("pos") String pos
);
}
activity_sub_category.xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SubCategoryActivity"
android:background="#color/cardview_light_background"
android:orientation="vertical">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/subFrameLayoutTop1"
android:background="#color/gray_light"
>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/subRecyclerViewTop1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
<FrameLayout
android:id="#+id/subFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/subRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:scrollbarStyle="outsideInset"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarFadeDuration="#integer/material_motion_duration_short_1"
/>
</FrameLayout>
</LinearLayout>
I tried to implement nested recycler view concept, but it's not working.

Having trouble with switchbuttons in RecyclerView

I am new to Android Studio and Firebase-programming.
I am trying to write a simple shoplist-app with a RecyclerView where every item holds a TextView and a Switch-button.
If i add more than seven items to the RecyclerView the switchbuttons start to behave very strange and checks several other switchbuttons. I am aware of the recycling of every list item in RecyclerView and have tried to google this "problem" but haven't found a way to implement other peoples answers in to my code. I think I have screwed up the Adapter or ViewHolder in some way.
Here is my adapter:
public class ListAdapter extends RecyclerView.Adapter<ShoppingItemViewHolder> {
private ArrayList<ShoppingItem> mShoppingItems = new ArrayList<>();
#NonNull
#Override
public ShoppingItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context mContext = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(mContext);
View listItemView = inflater.inflate(R.layout.list_item, parent, false);
Switch boughtSwitch = listItemView.findViewById(R.id.boughtSwitchId);
TextView itemTextView = listItemView.findViewById(R.id.itemTextView);
return new ShoppingItemViewHolder(listItemView);
}
#Override
public void onBindViewHolder(#NonNull ShoppingItemViewHolder holder, int position) {
ShoppingItem shoppingItem = mShoppingItems.get(position);
holder.bind(shoppingItem);
}
#Override
public int getItemCount() {
return mShoppingItems.size();
}
public void addItem(ShoppingItem shoppingItem){
mShoppingItems.add(shoppingItem);
notifyDataSetChanged();
}
public void removeItem(ShoppingItem shoppingItem){
mShoppingItems.remove(shoppingItem);
notifyDataSetChanged();
}
#Override
public long getItemId(int position) {
return position;
}
And here is my 'ShoppingItem'ViewHolder (Separate file, if that is a problem?) :
class ShoppingItemViewHolder extends RecyclerView.ViewHolder {
private final TextView productName;
private final Switch boughtSwitch;
public static final String ITEMS_FIREBASE_KEY = "ItemsList";
DatabaseReference ref = FirebaseDatabase.getInstance().getReference(ITEMS_FIREBASE_KEY);
public ShoppingItemViewHolder(View view) {
super(view);
productName = view.findViewById(R.id.itemTextView);
boughtSwitch = view.findViewById(R.id.boughtSwitchId);
}
public void bind(final ShoppingItem shoppingItem){
productName.setText(shoppingItem.productName);
boughtSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
boughtSwitch.setText("Köpt!");
shoppingItem.bought = true;
ref.child(shoppingItem.pushKey).child("bought").setValue(true);
} else {
boughtSwitch.setText("Köpt?");
shoppingItem.bought = false;
ref.child(shoppingItem.pushKey).child("bought").setValue(false);
}
}
});
boughtSwitch.setChecked(shoppingItem.bought);
}
And my MainActivity:
public class MainActivity extends AppCompatActivity
implements ChildEventListener{
private ArrayList<ShoppingItem> shoppingItems = new ArrayList<>();
public static final String ITEMS_FIREBASE_KEY = "ItemsList";
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference ref = firebaseDatabase.getReference(ITEMS_FIREBASE_KEY);
private TextView itemText;
private RecyclerView itemList;
private ListAdapter itemAdapter;
private EditText itemEntry;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemList = findViewById(R.id.item_recycler_list);
itemList.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL, false));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
itemText = findViewById(R.id.itemTextView);
itemEntry = findViewById(R.id.addItemEditText);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
// .setAction("Action", null).show();
pushToFirebase();
}
});
itemAdapter = new ListAdapter();
itemList.setAdapter(itemAdapter);
ref.addChildEventListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
removeItemsFromFirebase();
return true;
}
return super.onOptionsItemSelected(item);
}
private void pushToFirebase() {
String item = itemEntry.getText().toString();
boolean bought = false;
ShoppingItem shoppingItem = new ShoppingItem(item, bought);
shoppingItem.pushKey = ref.push().getKey();
ref.child(shoppingItem.pushKey).setValue(shoppingItem);
}
private void removeItemsFromFirebase() {
DatabaseReference queryRef = FirebaseDatabase.getInstance().getReference(ITEMS_FIREBASE_KEY);
Query boughtQuery = queryRef.child(ITEMS_FIREBASE_KEY).orderByChild("bought").equalTo(true);
boughtQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot querySnap : dataSnapshot.getChildren()){
querySnap.getRef().removeValue();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ShoppingItem recievedShoppingItem = dataSnapshot.getValue(ShoppingItem.class);
itemAdapter.addItem(recievedShoppingItem);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
itemAdapter.clearItemList();
ShoppingItem recievedShoppingItem = dataSnapshot.getValue(ShoppingItem.class);
itemAdapter.addItem(recievedShoppingItem);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
ShoppingItem recievedShoppingItem = dataSnapshot.getValue(ShoppingItem.class);
itemAdapter.removeItem(recievedShoppingItem);
itemAdapter.notifyDataSetChanged();
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
itemAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
EDIT:
Here is my "list_item.xml":
<?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:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/itemTextView"
android:layout_width="218dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
android:textSize="20dp" />
<Switch
android:id="#+id/boughtSwitchId"
android:layout_width="113dp"
android:layout_height="49dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="#string/bought_switch_text" />
I know it's a lot to go through but I would really appreciate if someone tries to help me.
I managed to make it work using Firebase UI database.
That way i didn't have to write my own methods for the adapater on Childlisteners.
Can post code if someone wants to!

RecyclerView inside nestedscrollview with bottom sheet behavior

I am making an app that displays post activities of different users like facebook. I have made postList Activity, in which username, his post image and post text will be displayed. Also want to implement like and comment feature in my app. On comment textview, bottomsheet will appear with list of comments of different users.
Problem is that i have used nestedscrollview with bottomsheet behavior. Inside nestedscroll view, there is recycler view.
here is my xml layout of bottomsheet
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottom_sheet1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
android:fillViewport="true"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="80dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/commentList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
This is Post List xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/post_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/addNewPost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
</ScrollView>
<include layout="#layout/bottom_sheet" />
This is postlist adapter
public class CustomAdapter extends RecyclerView.Adapter<ViewHolder> {
NestedScrollView bottom_sheet;
CoordinatorLayout mainLayout;
private BottomSheetBehavior mBottomSheetBehavior;
public CustomAdapter(Context context, ArrayList<Post> posts,NestedScrollView
bottom_sheet,CoordinatorLayout mainLayout) {
this.posts = posts;
this.context = context;
this.bottom_sheet=bottom_sheet;
this.mainLayout=mainLayout;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
mBottomSheetBehavior = BottomSheetBehavior.from(bottom_sheet);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
break;
case BottomSheetBehavior.STATE_EXPANDED: {
}
break;
case BottomSheetBehavior.STATE_COLLAPSED: {
}
break;
case BottomSheetBehavior.STATE_DRAGGING:
break;
case BottomSheetBehavior.STATE_SETTLING:
break;
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
holder.comment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mBottomSheetBehavior.getState() != BottomSheetBehavior.STATE_EXPANDED) {
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
} else {
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
});
}
#Override
public int getItemCount() {
return posts.size();
}
}
And this is the adapter for comments
public class CommentAdapter extends RecyclerView.Adapter<CommentViewHolder> {
Context context;
public CommentAdapter(Context context,ArrayList<Comment> comments) {
this.comments = comments;
this.context=context;
}
#Override
public CommentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment_layout, parent, false);
CommentViewHolder viewHolder = new CommentViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(CommentViewHolder holder, int position) {
firebaseDatabase = FirebaseDatabase.getInstance();
commentReference = firebaseDatabase.getReference().child("Comments");
mAuth = FirebaseAuth.getInstance();
uId = mAuth.getCurrentUser().getUid();
final Comment comment = comments.get(position);
holder.commentUName.setText("Numrah");
holder.commentText.setText("hello");
holder.addCommentBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "comment", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return comments.size();
}
}
PostList Activity
public class PostList extends AppCompatActivity {
RecyclerView recyclerView;
ArrayList<Post> posts;
CustomAdapter customAdapter;
FloatingActionButton addPost;
FirebaseDatabase firebaseDatabase;
DatabaseReference postReference;
DatabaseReference likeReference;
DatabaseReference commentReference;
NestedScrollView bottomSheet;
CoordinatorLayout mainLayout;
private BottomSheetBehavior mBottomSheetBehavior;
RecyclerView commentRecyclerView;
ArrayList<Comment> comments;
CommentAdapter commentAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_list);
bottomSheet = (NestedScrollView) findViewById(R.id.bottom_sheet1);
mainLayout = (CoordinatorLayout) findViewById(R.id.main_layout);
commentRecyclerView=bottomSheet.findViewById(R.id.commentList);
comments = new ArrayList<>();
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
//layoutManager.setAutoMeasureEnabled(true);
commentRecyclerView.setLayoutManager(layoutManager);
commentRecyclerView.setNestedScrollingEnabled(false);
commentAdapter = new CommentAdapter(this, comments);
commentRecyclerView.setAdapter(commentAdapter);
firebaseDatabase = FirebaseDatabase.getInstance();
postReference = firebaseDatabase.getReference("Post");
likeReference = firebaseDatabase.getReference("Likes");
commentReference = firebaseDatabase.getReference("Comments");
posts = new ArrayList<>();
addPost = (FloatingActionButton) findViewById(R.id.addNewPost);
recyclerView = (RecyclerView) findViewById(R.id.post_list);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
customAdapter = new CustomAdapter(this, posts, bottomSheet, mainLayout);
recyclerView.setAdapter(customAdapter);
addPost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(PostList.this, AddPost.class));
}
});
postReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Post post = dataSnapshot.getValue(Post.class);
posts.add(post);
customAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Post post = dataSnapshot.getValue(Post.class);
int indexOfItem = posts.indexOf(post);
if (indexOfItem >= 0) {
posts.set(indexOfItem, post);
}
customAdapter.notifyDataSetChanged();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onBackPressed() {
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
if (mBottomSheetBehavior.getState() != BottomSheetBehavior.STATE_EXPANDED) {
super.onBackPressed();
} else {
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
}
As your arraylist comments is empty ( comments.size() is 0 ) the getItemCount() of your CommentAdapter is returning 0 . Hence zero rows will be inflated and your recyclerView would be blank. So your test case wont be executed To execute your test case try this in your CommentAdapter :-
#Override
public int getItemCount() {
return 5; // returning static no of items
}

Recycler View not showing views properly in height and width parameter

I have been working on an app in which recycler view is used. This is what I wish it to be looked:
but right now, my code is showing like this:
I have like stuck at this point where views are not properly created in recyclerview {like 3-4 blank tabs in starting) and i need my app to look better. I am attaching my code below:
MainActivity Code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private CustomAdapter customAdapter;
ListView listView;
public Cursor cursor;
public StudentRepo studentRepo;
private final static String TAG = MainActivity.class.getName().toString();
private static final String TAG_BOOKMARKS="bookmarks";
private static final String TAG_ABOUT_US="about";
//recyclerView implementation
private List<TopSample> wordlist=new ArrayList<>();
private RecyclerView recyclerView;
private StudentAdapter studentAdapter;
//recyclerView implementation done
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
studentRepo = new StudentRepo(this);
recyclerView=(RecyclerView)findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
databaseAccess.open();
Cursor cursor= databaseAccess.getInfo();
cursor.moveToFirst();
do{
TopSample topSample=new TopSample(cursor.getString(0));
wordlist.add(topSample);
}while (cursor.moveToNext());
databaseAccess.close();
studentAdapter=new StudentAdapter(wordlist);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(studentAdapter);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
TopSample topSample= wordlist.get(position);
Intent intent = new Intent(MainActivity.this, SearchResult.class);
intent.putExtra(SearchResult.EXTRA_NO, (int) position);
startActivity(intent);
}
#Override
public void onLongClick(View view, int position) {
}
}));
//Done recyclerview implement
ImageView imageView=new ImageView(this);
imageView.setImageResource(R.drawable.button_action);
FloatingActionButton actionButton = new FloatingActionButton.Builder(this)
.setContentView(imageView)
.build();
ImageView Bookmarks=new ImageView(this);
Bookmarks.setImageResource(R.drawable.button_action);
ImageView Aboutus=new ImageView(this);
Aboutus.setImageResource(R.drawable.button_action);
SubActionButton.Builder itemBuilder = new SubActionButton.Builder(this);
SubActionButton buttonbookmark = itemBuilder.setContentView(Bookmarks).build();
SubActionButton buttonaboutus = itemBuilder.setContentView(Aboutus).build();
buttonbookmark.setOnClickListener(this);
buttonaboutus.setOnClickListener(this);
buttonbookmark.setTag(TAG_BOOKMARKS);
buttonaboutus.setTag(TAG_ABOUT_US);
FloatingActionMenu actionMenu = new FloatingActionMenu.Builder(this)
.addSubActionView(buttonbookmark)
.addSubActionView(buttonaboutus)
.attachTo(actionButton)
.build();
}
public interface ClickListener{
void onClick(View view, int position);
void onLongClick (View view, int position);
}
public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private GestureDetector gestureDetector;
private MainActivity.ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView,final MainActivity.ClickListener clickListener){
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
#Override
public void onResume() {
super.onResume();
}
#Override
///#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();
search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
Log.d(TAG, "onQueryTextSubmit ");
//cursor = studentRepo.getStudentListByKeyword(s);
// if (cursor == null) {
// Toast.makeText(MainActivity.this, "No records found!", Toast.LENGTH_LONG).show();
// } else {
// Toast.makeText(MainActivity.this, cursor.getCount() + " records found!", Toast.LENGTH_LONG).show();
// }/
//customAdapter.swapCursor(cursor);
return false;
}
#Override
public boolean onQueryTextChange(String s) {
Log.d(TAG, "onQueryTextChange ");
final List<TopSample>filteredmodellist=filter(wordlist,s);
studentAdapter.setFilter(filteredmodellist);
// cursor = studentRepo.getStudentListByKeyword(s);
// if (cursor != null) {
// customAdapter.swapCursor(cursor);
// }
return true;
}
private List<TopSample>filter(List<TopSample>models,String query){
query=query.toLowerCase();
final List<TopSample>fliterdModelList=new ArrayList<>();
for(TopSample model:models){
final String text=model.getVocab().toLowerCase();
if (text.contains(query)){
fliterdModelList.add(model);
}
}
return fliterdModelList;
}
});
return true;
}
#Override
public void onClick(View v) {
if (v.getTag().equals(TAG_BOOKMARKS)){
startActivity(new Intent(this,Bookmarks.class));
}
if (v.getTag().equals(TAG_ABOUT_US)){
}
}
}
StudentAdapter file:
public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.MyViewHolder> {
private List<TopSample> wordslist= Collections.emptyList();
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView sword;
public MyViewHolder(View view){
super(view);
sword=(TextView)view.findViewById(R.id.vocab);
}
}
public StudentAdapter(List<TopSample> wordslist){
this.wordslist=wordslist;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView=LayoutInflater.from(parent.getContext()).inflate(R.layout.dictionary_list_row,parent,false);
MyViewHolder vh=new MyViewHolder(itemView);
return vh;
//return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
TopSample sample=wordslist.get(position);
holder.sword.setText(sample.getVocab());
}
#Override
public int getItemCount() {
return wordslist.size();
}
//SearchinRecyclerview
public void setFilter(List<TopSample> mTopSamples){
wordslist=new ArrayList<>();
wordslist.addAll(mTopSamples);
notifyDataSetChanged();
}
//SearchinRecyclerview end
}
dictionary_list_row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:clickable="true"
android:focusableInTouchMode="true"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/vocab"
android:textStyle="bold"
android:textSize="20sp"
/>
</LinearLayout>
content_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_main"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
Update your dictionary_list_row.xml
<?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="wrap_content"
android:layout_margin="20dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<TextView
android:id="#+id/vocab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Country Name"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Code"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
Update:
Make some change here add if section
DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
databaseAccess.open();
Cursor cursor= databaseAccess.getInfo();
cursor.moveToFirst();
do{
if(cursor.getString(0) != null){
TopSample topSample=new TopSample(cursor.getString(0));
wordlist.add(topSample);
}
}while (cursor.moveToNext());
databaseAccess.close();

Edittext in RecylerView start lossing data

hii i am working in android application in which there is recycler view with each row is edittext, as i click on floating button new edittext is added in which user can enter email,my problem is that after say 9th position the previously enterd email values replaced with some position , i am calling notifydatasetchanged() method below is the code...if anyone know the way plese share..
1)Challenge Invite_other.java
/**
* Add custom workout detail
*/
public class ChallengeInviteOtherActivity extends GlobalAppCompactActivity implements ResponseListener {
private Gson gson;
private List<ChallengeParticipant> challengeParticipants;
private RecyclerView mRecyclerView;
private ChallengeInviteOtherAdapter adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.challenge_invite_other);
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
initlization();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.floating_add_custom_challenge);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
challengeParticipants.add(new ChallengeParticipant());
adapter.addAll(challengeParticipants);
}
});
setTitle(getString(R.string.nav_invite_participant));
//progressDialog = new ProgressDialog(this, R.style.CustomProgressDialog);
}
private void initlization() {
gson = CommonUtil.getGson();
challengeParticipants = new ArrayList<ChallengeParticipant>();
mRecyclerView = (RecyclerView) findViewById(R.id.challenge_list_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
challengeParticipants.add(new ChallengeParticipant());
adapter = new ChallengeInviteOtherAdapter(this);
adapter.addAll(challengeParticipants);
mRecyclerView.setAdapter(adapter);
}
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}else if (item.getItemId() == R.id.action_bar_trace_friend) {
List<ChallengeParticipant> challengeParticipantList = new ArrayList<ChallengeParticipant>();
for (ChallengeParticipant participant : challengeParticipants) {
if (CommonUtil.isNotNull(participant.getEmailAddress()) || CommonUtil.isNotNull(participant.getContactNo())) {
participant.setChallengeId(CommonUtil.CHALLENGE.getId());
challengeParticipantList.add(participant);
}
}
if(challengeParticipantList.size()==0){
AlertMsg.showToast(this, getString(R.string.at_least_fill_one_contact));
}else{
Type listType = new TypeToken<ArrayList<ChallengeParticipant>>() {
}.getType();
String json = CommonUtil.getGson().toJson(challengeParticipantList, listType);
VolleyRequest volleyRequest = VolleyRequest.getInstance();
volleyRequest.sendRequest(VolleyRequest.INVITE_PARTICIPANTS, json, CommonUtil.getObject(this, this));
}
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.clear();
getMenuInflater().inflate(R.menu.challenge_invite_participant_memu, menu);
getMenuInflater().inflate(R.menu.common, menu);
return true;
}
#Override
public void onResponse(Object... result) {
AlertMsg.showToast(this, getString(R.string.invite_successfully));
finish();
}
//private ProgressDialog progressDialog;
}
2)Adapter class
private List<ChallengeParticipant> itemDetailsrrayList;
private LayoutInflater layoutInflater;
private Context mContext;
public ChallengeInviteOtherAdapter(Context context) {
mContext = context;
layoutInflater = LayoutInflater.from(context);
}
class MyViewHolder extends RecyclerView.ViewHolder {
private EditText email;
public MyViewHolder(View view) {
super(view);
email = (EditText) view.findViewById(R.id.email);
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.challenge_invite_other_item_detail, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final ChallengeParticipant c = itemDetailsrrayList.get(position);
holder.email.setText(c.getEmailAddress());
//holder.phone.setText(c.getContactNo());
//RecyclerView recyclerView = (RecyclerView) ((Activity) mContext).findViewById(R.id.price_listview);
//recyclerView.getLayoutParams().height = 150*itemDetailsrrayList.size();
holder.email.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(CommonUtil.isEmail(holder.email.getText().toString())){
c.setEmailAddress(holder.email.getText().toString());
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
/*holder.email.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if (!b) {
}
}
});*/
/* holder.phone.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if (!b) {
if(CommonUtil.isPhone(holder.phone.getText().toString())){
c.setContactNo(holder.phone.getText().toString());
}
}
}
});*/
}
public void addAll(List<ChallengeParticipant> list) {
itemDetailsrrayList = list;
notifyItemInserted(itemDetailsrrayList.size());
}
#Override
public int getItemCount() {
return itemDetailsrrayList.size();
}
}
3)xml layout of activity
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/dim_background"
android:focusableInTouchMode="true"
android:orientation="vertical">
<include layout="#layout/toolbar" />
<!--<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="#string/or"/>-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:elevation="#dimen/general_elevation"
android:layout_margin="10dp"
android:background="#color/cardview_light_background">
<include layout="#layout/textview_no_record_found" />
<android.support.v7.widget.RecyclerView
android:id="#+id/challenge_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/floating_add_custom_challenge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:elevation="12dp"
android:src="#drawable/ic_add_white_24dp"
app:backgroundTint="#color/colorAccent"
app:borderWidth="0dp"
app:fabSize="normal"/>
</FrameLayout>
<include
layout="#layout/ad_system"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</LinearLayout>
When You add the new data to Array on which you set the adapter than Notify the adapter Add below lines after calling adapter.addAll(challengeParticipants);
adapter.notifyDataSetChanged();
adapter.notifyItemInserted(challengeParticipants.size());
Try this
public void addAll(List<ChallengeParticipant> list) {
itemDetailsrrayList = list;
notifyItemRangeChanged(0,challengeParticipants.size()-1);
}

Categories

Resources