I need sort alphabetically in my custom ListView. In list_item, I have TextImage and two TextView (app name, package name) and can't understand how sort by alphabet app name:
My list item:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal">
<ImageView
android:id="#+id/app_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:padding="4dp"
android:scaleType="centerCrop"
android:contentDescription="#null"
tools:src="#mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|center_vertical"
android:orientation="vertical"
android:paddingLeft="8dp">
<TextView
android:id="#+id/tv_app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textStyle="bold"
tools:text="Application name"/>
<TextView
android:id="#+id/tv_app_package"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textStyle="bold"
tools:text="app.package.name"/>
</LinearLayout>
</LinearLayout>
And my adapter:
public class ListViewAdapter extends ArrayAdapter{
private Context context;
private List mItem;
private PackageManager packageManager;
public ListViewAdapter(Context context, int list_item, List items) {
super(context, R.layout.list_item, items);
this.context = context;
this.mItem = items;
packageManager = context.getPackageManager();
}
public int getCount(){
return ((null != mItem) ? mItem.size() : 0);
}
#Override
public ApplicationInfo getItem(int position) {
return (null != mItem) ? (ApplicationInfo) mItem.get(position) : null;
}
public long getItemId(int position){
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
if (null == view) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item, null);
}
ApplicationInfo data = (ApplicationInfo) mItem.get(position);
if (null != data){
TextView appName = (TextView) view.findViewById(R.id.tv_app_name);
TextView appPackage = (TextView) view.findViewById(R.id.tv_app_package);
ImageView icon = (ImageView) view.findViewById(R.id.app_icon);
appName.setText(data.loadLabel(packageManager));
appPackage.setText(data.packageName);
icon.setImageDrawable(data.loadIcon(packageManager));
}
return view;
}
}
My fragment in which show ListView
public class ResultFragment extends ListFragment {
private PackageManager packageManager = null;
private ListViewAdapter listViewAdapter = null;
private List mItem;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
packageManager = getContext().getPackageManager();
new LoadApplications().execute();
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
ApplicationInfo applicationInfo = (ApplicationInfo) mItem.get(position);
try{
Intent intent = packageManager.getLaunchIntentForPackage(applicationInfo.packageName);
if (intent != null){
startActivity(intent);
}
}catch (ActivityNotFoundException e){
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
}catch (Exception e){
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}
private List<ApplicationInfo> checkForLauncherIntent(List<ApplicationInfo> list){
ArrayList mItem = new ArrayList();
for(ApplicationInfo info : list) {
try{
if(packageManager.getLaunchIntentForPackage(info.packageName) != null) {
mItem.add(info);
}
} catch(Exception e) {
e.printStackTrace();
}
}
return mItem;
}
private class LoadApplications extends AsyncTask<Void, Void, Void>{
private ProgressDialog progressDialog = null;
#Override
protected Void doInBackground(Void... params){
mItem = checkForLauncherIntent(packageManager.getInstalledApplications(PackageManager.GET_META_DATA));
listViewAdapter = new ListViewAdapter(getActivity(), R.layout.list_item, mItem);
return null;
}
#Override
protected void onPostExecute(Void result){
setListAdapter(listViewAdapter);
progressDialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onPreExecute(){
progressDialog = ProgressDialog.show(getActivity(), null, "Loading file info...");
super.onPreExecute();
}
}
}
Please help me by sorting my list alphabetically.
From Android Documentation
public abstract android.content.Intent
getLaunchIntentForPackage(java.lang.String packageName)
Returns a
"good" intent to launch a front-door activity in a package. This is
used, for example, to implement an "open" button when browsing through
packages. The current implementation looks first for a main activity
in the category Intent.CATEGORY_INFO, and next for a main activity in
the category Intent.CATEGORY_LAUNCHER. Returns null if neither are
found.
Parameters: packageName - The name of the package to inspect.
Returns: A fully-qualified Intent that can be used to launch the main
activity in the package. Returns null if the package does not contain
such an activity, or if packageName is not recognized.
You need to make some changes in your code
private ArrayList<ResolveInfo> checkForLauncherIntent(List<ApplicationInfo> list){
ArrayList<ResolveInfo> mItems = new ArrayList();
for(ApplicationInfo info : list) {
try{
if(packageManager.getLaunchIntentForPackage(info.packageName) != null) {
Intent intent = packageManager.getLaunchIntentForPackage(info.packageName));
ResolveInfo app = packageManager.resolveActivity(intent,0);
mItems.add(app);
}
} catch(Exception e) {
e.printStackTrace();
}
}
return mItems;
}
in your asn task
private class LoadApplications extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params){
ArrayList<ResolveInfo> mItem = checkForLauncherIntent(packageManager.getInstalledApplications(PackageManager.GET_META_DATA));
listViewAdapter = new ListViewAdapter(ctx, mItem);
return null;
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
listView.setAdapter(listViewAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ResolveInfo resolveInfo = listViewAdapter.getItem(position);
ActivityInfo activityInfo = resolveInfo.activityInfo;
ComponentName name = new ComponentName(activityInfo.applicationInfo.packageName,activityInfo.name);
Intent intent = new Intent();
intent.setComponent(name);
startActivity(intent);
}
});
}
#Override
protected void onPreExecute(){
super.onPreExecute();
//progressDialog = ProgressDialog.show(getActivity(), null, "Loading file info...");
}
}
In your adapter constructor
public class ListViewAdapter extends BaseAdapter {
private Context context;
private ArrayList<ResolveInfo> mItem;
private PackageManager packageManager;
public ListViewAdapter(Context context, ArrayList<ResolveInfo> items) {
this.context = context;
this.mItem = items;
packageManager = context.getPackageManager();
Collections.sort(mItem,new ResolveInfo.DisplayNameComparator(packageManager));
}
public int getCount(){
return mItem.size();
}
#Override
public ResolveInfo getItem(int position) {
return mItem.get(position);
}
public long getItemId(int position){
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.testa, null);
}
ResolveInfo app = mItem.get(position);
TextView appName = (TextView) convertView.findViewById(R.id.tv_app_name);
TextView appPackage = (TextView) convertView.findViewById(R.id.tv_app_package);
ImageView icon = (ImageView) convertView.findViewById(R.id.app_icon);
ActivityInfo activity = app.activityInfo;
appPackage.setText(activity.applicationInfo.packageName);
appName.setText(app.loadLabel(packageManager));
icon.setImageDrawable(app.loadIcon(packageManager));
return convertView;
}
}
Find the entire project At Github
First change The Chinese to pinyin you can use the jar pinyin4j-2.5.0.jar
then maybe you can try this method
Arrays.sort(arrayList,String.CASE_INSENSITIVE_ORDER);
Do this it will work
Create a class comparator like this
public class CustomComparator implements Comparator<ApplicationInfo> {
#Override
public int compare(ApplicationInfo o1, ApplicationInfo o2) {
return o1.loadLabel(packageManager).toString().compareTo(o2.loadLabel(packageManager).toString());
}
}
Now use this class in the Async Task where you are creating the adapter
Collections.sort(mItem, new CustomComparator());
listViewAdapter = new ListViewAdapter(context, mItem);
it will sort your list
Let me know in case of more issue
use this method when you need to sort in listview,
Collections.sort(apps, new Comparator<App>() {
#Override
public int compare(App lhs, App rhs) {
//here getTitle() method return app name...
return lhs.getTitle().compareTo(rhs.getTitle());
}
});
Please try this.
public class MainActivity extends AppCompatActivity {
private ArrayList<UserInfo> userInfos;
private CustomListAdapter customListAdapter;
private ListView customListView;
private String[] names={
"3 Khan",
"2 Ahmed",
"1 Iqbal"
};
private String[] professions={
"Rank 1",
"Rank 2",
"Rank 3"
};
private int[] photos={
R.drawable.sample_5,
R.drawable.sample_1,
R.drawable.sample_6
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setSupportActionBar((Toolbar)findViewById(R.id.toolbar));
customListView=(ListView)findViewById(R.id.custom_list_view);
userInfos=new ArrayList<>();
Arrays.sort(names,String.CASE_INSENSITIVE_ORDER);
customListAdapter=new CustomListAdapter(userInfos,this);
customListView.setAdapter(customListAdapter);
getDatas();
customListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(MainActivity.this, "Name : " + names[i] + "\n Profession : " + professions[i], Toast.LENGTH_SHORT).show();
}
});
}
// getting all the datas
private void getDatas(){
for(int count=0;count<names.length;count++){
userInfos.add(new UserInfo(names[count],professions[count],photos[count]));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_option,menu);
MenuItem menuItem=menu.findItem(R.id.search);
SearchView searchView=(SearchView)menuItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
newText=newText.toString();
ArrayList<UserInfo> newUserInfos=new ArrayList<>();
for(UserInfo userInfo:userInfos){
String name=userInfo.getName().toLowerCase();
String profession=userInfo.getProfession().toLowerCase();
if(name.contains(newText) || profession.contains(newText)){
newUserInfos.add(userInfo);
}
}
customListAdapter.filterResult(newUserInfos);
customListAdapter.notifyDataSetChanged();
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
}```
Related
I have a project in android studio that loads data from an online database and put that data in a listview. Above the listview there is an EditText that i want to search the listview with the value that i write inside. I tried to adapt this tutorial to mine but i get many errors and crashes that i cannot fix becaue i am a noob. Can you help me to adapt the tutorial to my project please? Below is my code without the search filter. If you want i can upload my try with the errors. Thank you in advance!
AllStudents.java:
public class AllStudents extends AppCompatActivity {
ListView StudentListView;
ProgressBar progressBar;
String HttpUrl = "http://sissy-nickels.000webhostapp.com/AllStudentData.php";
List<String> IdList = new ArrayList<>();
String LessonName;
HttpParse httpParse = new HttpParse();
ProgressDialog pDialog;
String FinalJSonObject;
HashMap<String,String> ResultHash = new HashMap<>();
String ParseResult ;
List<Student> studentList;
#Override
public void onBackPressed()
{
super.onBackPressed();
startActivity(new Intent(AllStudents.this, AddStudent.class));
finish();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_allstudents);
StudentListView = (ListView)findViewById(R.id.listview2);
progressBar = (ProgressBar)findViewById(R.id.progressBar);
LessonName = getIntent().getStringExtra("Lesson");
HttpWebCall(LessonName);
//Adding ListView Item click Listener.
StudentListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
Intent intent = new Intent(AllStudents.this,SingleStudent.class);
// Sending ListView clicked value using intent.
intent.putExtra("ListViewValue", IdList.get(position).toString());
startActivity(intent);
//Finishing current activity after open next activity.
finish();
}
});
}
public void HttpWebCall(final String LessonName){
class HttpWebCallFunction extends AsyncTask<String,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = ProgressDialog.show(AllStudents.this,"Loading Data",null,true,true);
}
#Override
protected void onPostExecute(String httpResponseMsg) {
super.onPostExecute(httpResponseMsg);
pDialog.dismiss();
//Storing Complete JSon Object into String Variable.
FinalJSonObject = httpResponseMsg ;
//Parsing the Stored JSOn String to GetHttpResponse Method.
new GetHttpResponse(AllStudents.this).execute();
}
#Override
protected String doInBackground(String... params) {
ResultHash.put("LessonName",params[0]);
ParseResult = httpParse.postRequest(ResultHash, HttpUrl);
return ParseResult;
}
}
HttpWebCallFunction httpWebCallFunction = new HttpWebCallFunction();
httpWebCallFunction.execute(LessonName);
}
// JSON parse class started from here.
private class GetHttpResponse extends AsyncTask<Void, Void, Void>
{
public Context context;
public GetHttpResponse(Context context)
{
this.context = context;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0)
{
try
{
if(FinalJSonObject != null)
{
JSONArray jsonArray = null;
try {
jsonArray = new JSONArray(FinalJSonObject);
JSONObject jsonObject;
Student student;
studentList = new ArrayList<Student>();
for(int i=0; i<jsonArray.length(); i++)
{
jsonObject = jsonArray.getJSONObject(i);
student = new Student();
// Adding Student Id TO IdList Array.
IdList.add(jsonObject.getString("id").toString());
//Adding Student Name.
student.StudentName = jsonObject.getString("Regnum").toString();
studentList.add(student);
}
}
catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
progressBar.setVisibility(View.GONE);
StudentListView.setVisibility(View.VISIBLE);
ListAdapter adapter = new ListAdapter(studentList, context);
StudentListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}}
ListAdapter.java
public class ListAdapter extends BaseAdapter {
Context context;
List<Student> valueList=null;
public ListAdapter(List<Student> listValue, Context context)
{
this.context = context;
this.valueList = listValue;
if(valueList==null){
valueList = new ArrayList<>();
}
}
#Override
public int getCount()
{
return this.valueList.size();
}
#Override
public Object getItem(int position)
{
return this.valueList.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewItem viewItem;
convertView = null;
if(convertView == null)
{
viewItem = new ViewItem();
LayoutInflater layoutInfiater = (LayoutInflater)this.context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = layoutInfiater.inflate(R.layout.listviewitem, null);
viewItem.TextViewStudentName = (TextView)convertView.findViewById(R.id.textView1);
convertView.setTag(viewItem);
}
else
{
viewItem = (ViewItem) convertView.getTag();
}
viewItem.TextViewStudentName.setText(valueList.get(position).StudentName);
return convertView;
}}class ViewItem{ TextView TextViewStudentName;}
Student.java:
public class Student {
public String StudentName ;}
listview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/gradient"
android:padding="15dp">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textColor="#android:color/holo_blue_dark"
android:textSize="24dp" />
avtivity_allstudents.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_show_all_students"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.djale.login_register.AllStudents"
android:background="#drawable/gradient"
>
<EditText
android:id="#+id/search"
android:layout_width="250dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:background="#11000000"
android:ems="10"
android:drawableLeft="#drawable/ic_search_black_24dp"
android:hint=" Search by reg. number"
android:inputType="textPersonName"
android:textColorHint="#android:color/holo_blue_dark"
android:textSize="18sp" />
<ListView
android:id="#+id/listview2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_below="#+id/search" />
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="visible"
/>
You can do like this :
search=(EditText)findviewById(R.id.search);
search.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
searchList=new ArrayList<>();
for(studentList name: String){
if(name.toLowerCase().contains(editable.toString().toLowerCase())){
searchList.add(name);
}
}
//clear data in adapter
//add searchList to your adapter
}
});
You can add TextChangedListener to your search box (which is a EditText). In onTextChanged(), filter list & update ListView accordingly.
In AllStudents.java, try making these changes:
public class AllStudents extends AppCompatActivity {
.....
#Override
protected void onCreate(Bundle savedInstanceState) {
....
StudentListView.setOnItemClickListener(...)
// add TextChangedListener to search box.
// It listens for user's entered text & filter students' list by name
EditText searchEditText = (EditText) findViewById(R.id.search);
searchEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged (CharSequence s, int start, int count, int after) {
}
// when text is entered in search box, filter list by search text
#Override
public void onTextChanged(CharSequence cs, int start, int before, int count) {
filterStudents(cs);
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
// check student's name whether contain text entered in search box
private void filterStudents (CharSequence cs) {
List<Student> filteredList = new ArrayList<>();
if (TextUtils.isEmpty(cs)) {
// no text is entered for search, do nothing
return;
}
// build new student list which filtered by search text.
for (Student student : studentList) {
if (student.StudentName.contains(cs)) {
filteredList.add(student);
}
}
// show filtered list in listview
ListAdapter adapter = new ListAdapter(filteredList, this);
StudentListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
I am trying to use TextChangedListener to implement search functionality on my ListView. But after adding some character in EditText; the ListView goes blank. I have implemented filter method in my ArrayAdapter class.
I am getting my data from JSON.
My Logcat shows: getSlotFromBufferLocked: unknown buffer
Is there any other way to search ListView?
Here's my code:
UserList.java
public class UserList extends AppCompatActivity {
private ListView listView;
private ArrayList<MyDataModel> list;
private MyArrayAdapter adapter;
private EditText search;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_list);
search = (EditText) findViewById(R.id.search);
//Array List for Binding Data from JSON to this List
list = new ArrayList<>();
//Binding that List to Adapter
adapter = new MyArrayAdapter(this, list);
//Getting List and Setting List Adapter
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
search.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) {
String text = search.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
#Override
public void afterTextChanged(Editable s) {
}
});
//Checking Internet Connection
if (InternetConnection.checkConnection(getApplicationContext())) {
new GetDataTask().execute();
} else {
Snackbar.make(findViewById(R.id.parentLayout),"Internet Connection Not Available", Snackbar.LENGTH_LONG).show();
}
}
//Creating Get Data Task for Getting Data From Web
class GetDataTask extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog;
int jIndex;
int x;
#Override
protected void onPreExecute() {
super.onPreExecute();
//Progress Dialog for User Interaction
x=list.size();
if(x==0)
jIndex=0;
else
jIndex=x;
dialog = new ProgressDialog(UserList.this);
dialog.setTitle("Please Wait..."+x);
dialog.setMessage("Retrieving Data");
dialog.show();
}
#Nullable
#Override
protected Void doInBackground(Void... params) {
//Getting JSON Object from Web Using okHttp
JSONObject jsonObject = JSONParser.getDataFromWeb();
try {
if (jsonObject != null) {
if(jsonObject.length() > 0) {
JSONArray array = jsonObject.getJSONArray(Keys.KEY_CONTACTS);
//Check Length of Array...
int lenArray = array.length();
if(lenArray > 0) {
for( ; jIndex < lenArray; jIndex++) {
//Creating Every time New Object and adding to List
MyDataModel model = new MyDataModel();
JSONObject innerObject = array.getJSONObject(jIndex);
String name = innerObject.getString(Keys.KEY_NAME);
model.setName(name);
list.add(model);
}
}
}
} else {
}
} catch (JSONException je) {
Log.i(JSONParser.TAG, "" + je.getLocalizedMessage());
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
dialog.dismiss();
//Checking if List size if more than zero then update ListView
if(list.size() > 0) {
adapter.notifyDataSetChanged();
} else {
Snackbar.make(findViewById(R.id.parentLayout), "No Data Found", Snackbar.LENGTH_LONG).show();
}
}
}
}
I have implemented the filter method in my ArrayAdapter class.
Here's my ArrayAdapter class:
MyArrayAdapter.java
public class MyArrayAdapter extends ArrayAdapter<MyDataModel> implements Filterable{
List<MyDataModel> modelList;
Context context;
private LayoutInflater mInflater;
private ArrayList<MyDataModel> arrayList;
public MyArrayAdapter(Context context, List<MyDataModel> objects) {
super(context, 0, objects);
this.context = context;
this.mInflater = LayoutInflater.from(context);
modelList = objects;
this.arrayList = new ArrayList<MyDataModel>();
this.arrayList.addAll(modelList);
}
#Override
public MyDataModel getItem(int position) {
return modelList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder vh;
if (convertView == null) {
View view = mInflater.inflate(R.layout.layout_row_view, parent, false);
vh = ViewHolder.create((RelativeLayout) view);
view.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
MyDataModel item = getItem(position);
vh.textViewName.setText(item.getName());
return vh.rootView;
}
private static class ViewHolder {
public final RelativeLayout rootView;
public final TextView textViewName;
private ViewHolder(RelativeLayout rootView, TextView textViewName) {
this.rootView = rootView;
this.textViewName = textViewName;
}
public static ViewHolder create(RelativeLayout rootView) {
TextView textViewName = (TextView) rootView.findViewById(R.id.textViewName);
return new ViewHolder(rootView, textViewName);
}
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
modelList.clear();
if (charText.length() == 0) {
modelList.addAll(arrayList);
} else {
for (MyDataModel wp : arrayList) {
if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
modelList.add(wp);
}
}
}
notifyDataSetChanged();
}
Try,
modelList = new ArrayList<MyDataModel>;
Write this line after modelList.clear(); and check.
Go with this link, and follow steps for implementing the same:
and the problem with buffer is called every textchanged listener will call everytime if you add or delete any character or space in it. So avoid using that. It will cause memory leak problems.
I creating an app that has a custom listview. My problem is it not functioning properly. Look at the image below . That's my custom listview.
Image 1
Then when i want try to search . This happen .
Image 2
As you can see. The text in the Edittext is not matching with the result in custom listview. But when i try to click the result in custom listview. it redirect me on the page of the edittext string. My only problem is the text result in custom listview is not matching with the text input in the edittext.
This is my codes.
ListViewAdapter.java
public class LstViewAdapter extends ArrayAdapter<ArrayList> implements Filterable {
private Context context;
private int resource;
private int id;
private LstViewAdapter adapter;
private ArrayList arrayList;
private FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
private Filter filter;
public LstViewAdapter(Context context, int resource, int id, ArrayList arrayList){
super(context, resource, id, arrayList);
this.context = context;
this.resource = resource;
this.id = id;
this.arrayList = arrayList;
this.adapter = this;
}
// Hold views of the ListView to improve its scrolling performance
private static class ViewHolder {
public TextView type;
public ImageButton removeButton;
}
public View getView(final int position, final View convertView, ViewGroup parent) {
View rowView = convertView;
// Inflate the list_item.xml file if convertView is null
if(rowView==null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView= inflater.inflate(resource, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.type= (TextView) rowView.findViewById(R.id.txt);
viewHolder.removeButton= (ImageButton) rowView.findViewById(btn_del);
rowView.setTag(viewHolder);
}
final String x = (String) arrayList.get(position);
final String y = arrayList.get(position).toString().trim();
// Set text to each TextView of ListView item
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.type.setText(x);
holder.removeButton.setBackgroundResource(R.drawable.deletes);
holder.removeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
AlertDialog.Builder builder2=new AlertDialog.Builder(context);
builder2.setTitle("Delete Class");
builder2.setMessage("Do you want to delete class "+y+"?");
final EditText input = new EditText(context);
input.setHint("hint");
builder2.setIcon(R.drawable.deletes);
builder2.setPositiveButton("Delete",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
arrayList.remove(position);
notifyDataSetChanged();
Toast.makeText(v.getContext(), "Class " + y + " has been deleted", Toast.LENGTH_SHORT).show();
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("users").child("teacher").child(user.getUid().toString().trim()).child("class").child(y);
mDatabase.setValue(null);
}
});
builder2.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog dialog = builder2.show();
}
});
return rowView;
}
#Override
public Filter getFilter() {
if (filter == null)
filter = new AppFilter<String>(arrayList);
return filter;
}
private class AppFilter<T> extends Filter {
private String sourceObjects;
public AppFilter(String objects) {
sourceObjects = new AppFilter<String>(arrayList);
synchronized (this) {
sourceObjects.addAll(objects);
}
}
#Override
protected FilterResults performFiltering(CharSequence chars) {
String filterSeq = chars.toString().toLowerCase();
FilterResults result = new FilterResults();
if (filterSeq != null && filterSeq.length() > 0) {
String filter = new AppFilter<String>(arrayList);
for (T object : sourceObjects) {
// the filtering itself:
if (object.toString().toLowerCase().contains(filterSeq))
filter.add(object);
}
result.count = filter.size();
result.values = filter;
} else {
// add all objects
synchronized (this) {
result.values = sourceObjects;
result.count = sourceObjects.size();
}
}
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// NOTE: this function is *always* called from the UI thread.
String filtered = (String) results.values;
notifyDataSetChanged();
clear();
for (int i = 0, l = filtered.size(); i < l; i++)
add((String) filtered.get(i));
notifyDataSetInvalidated();
}
}
}
MainActivity
public class MyClassesActivity extends AppCompatActivity {
private Button btnCreateClass;
private DatabaseReference mDatabase;
private ListView mUserList;
private ArrayList<String> mUsername = new ArrayList<>();
private FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
private FirebaseAuth auth;
final String userId = FirebaseAuth.getInstance().getCurrentUser().getUid().toString().trim();
String selectedItem, value;
LstViewAdapter arrayAdapter;
private EditText inputSearch;
int textlength = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_classes);
getSupportActionBar().setTitle("My Classes");
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
btnCreateClass = (Button) findViewById(R.id.createclass);
mUserList = (ListView) findViewById(R.id.userlist);
inputSearch = (EditText) findViewById(R.id.inputSearch);
inputSearch.setVisibility(View.GONE);
//get current user
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
arrayAdapter= new LstViewAdapter(this, R.layout.listitem,R.id.txt, mUsername);
mUserList.setAdapter(arrayAdapter);
mDatabase = FirebaseDatabase.getInstance().getReference().child("users").child("teacher").child(user.getUid().toString().trim()).child("class");
mDatabase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
value = dataSnapshot.getKey().toString().trim();
mUsername.add(value);
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
btnCreateClass.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MyClassesActivity.this, CreateClassActivity.class);
startActivity(intent);
}
});
mUserList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedItem = (String) parent.getItemAtPosition(position);
Intent intent = new Intent(MyClassesActivity.this, StudentListActivity.class);
intent.putExtra("secname", selectedItem);
startActivity(intent);
}
});
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
arrayAdapter.getFilter().filter(cs);
arrayAdapter.notifyDataSetChanged();
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
}
#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_class, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; goto parent activity.
this.finish();
return true;
default:
if (id == R.id.search) {
inputSearch.setVisibility(View.VISIBLE);
inputSearch.requestFocus();
//Do something
return true;
}
return super.onOptionsItemSelected(item);
}
}
}
listitem.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="10dp"
android:layout_alignParentLeft="true" />
<ImageButton
android:id="#+id/btn_del"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:src="#drawable/deletes"
android:onClick="onClick"
android:background="#android:color/transparent"
android:layout_alignParentRight="true" />
I have a RecyclerView getting external JSON data parsed from a server. It works fine however the Volley async task on JSON sometimes takes a while and when it does the fragment displays an empty blank view.
How can I create a test to check if the view is empty and display a msg if it is? I tried to check:
if (recyclerView == null)
if (jsonList == null)
if (adapter.getItemCount() == 0)
if (bundle == null)
But those tests either dont do anything or they display the error message every single time even if the RecyclerView is not empty.
This is the code on the fragment:
public void onViewCreated(View view, Bundle savedInstanceState) {
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.supportsPredictiveItemAnimations();
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setClickable(true);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
NovaAdapter novaAdapter = new NovaAdapter(getActivity(),jsonList);
if (novaAdapter.getItemCount() != 0) {
recyclerView.setAdapter(novaAdapter);
}else{
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Retrieving data from Server");
pDialog.show();
}
super.onViewCreated(view, savedInstanceState);
and the method on the Adapter:
#Override
public int getItemCount() {
return (null != novaList ? novaList.size() : 0);
}
The way it is now the progress dialog always run no matter if the view is empty or not.
UPDATE: Here's the adapter code:
public class NovaAdapter extends RecyclerView.Adapter<NovaListRowHolder> {
ArrayList<HashMap<String, String>> novaList = new ArrayList<HashMap<String, String>>();
public static final String STATUS = "status";
public static final String NAME = "name";
public static final String ID = "id";
private Context mContext;
public NovaAdapter(Context context, ArrayList<HashMap<String, String>> novaList) {
this.novaList = novaList;
this.mContext = context;
}
#Override
public NovaListRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.instances_list, null);
NovaListRowHolder mh = new NovaListRowHolder(v);
return mh;
}
#Override
public void onBindViewHolder(NovaListRowHolder novaListRowHolder, int i) {
HashMap<String, String> e = novaList.get(i);
novaListRowHolder.name.setText(e.get(NAME));
novaListRowHolder.status.setText(e.get(STATUS));
novaListRowHolder.setId(e.get(ID));
}
#Override
public int getItemCount() {
return (null != novaList ? novaList.size() : 0);
}class NovaListRowHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
protected TextView name;
protected TextView status;
protected String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public NovaListRowHolder(View view) {
super(view);
view.setOnClickListener(this);
this.name = (TextView) view.findViewById(R.id.nameInstance);
this.status = (TextView) view.findViewById(R.id.statusInstance);
}
public void onClick(View view){
Dialog dialog = new Dialog(view.getContext());
dialog.setContentView(R.layout.instances_listdetail);
dialog.setTitle("Details " + name.getText() + " " + getPosition());
dialog.show();
}
UPDATE2:
I updated another class which is pretty much the same as the one above with a callback interface however now the recyclerView displays for 1 second and then goes blank. The dialog doesn't even show. Here's the code:
public class SubnetsFragment extends Fragment implements OnJSONLoaded{
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
private OnFragmentInteractionListener mListener;
public ArrayList<HashMap<String, String>> jsonList;
public RecyclerView recyclerView;
public ProgressDialog pDialog;
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static SubnetsFragment newInstance(int sectionNumber) {
SubnetsFragment fragment = new SubnetsFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public SubnetsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle extras = getArguments();
Serializable parsedList = extras.getSerializable("SubnetsParsed");
jsonList = (ArrayList<HashMap<String, String>>)parsedList;
if (extras == null){
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
alert.setTitle("Token Expired");
alert.setMessage("Authentication Token expired! Please login again.")
.setNeutralButton("Connect", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(getActivity(), Login.class);
startActivity(intent);
getActivity().finish();
getFragmentManager().beginTransaction().remove(SubnetsFragment.this).commit();
}
});
AlertDialog alertDialog = alert.create();
alertDialog.show();
}
View rootView = inflater.inflate(R.layout.fragment_subnets, container, false);
recyclerView = (RecyclerView)rootView.findViewById(R.id.subnetsRV);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.supportsPredictiveItemAnimations();
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setClickable(true);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
onJsonLoaded(jsonList);
}
#Override
public void onJsonLoaded(ArrayList<HashMap<String, String>> list) {
SubnetsParser.setOnJSONLoadedListener(new OnJSONLoaded() {
#Override
public void onJsonLoaded(ArrayList<HashMap<String, String>> list) {
if (list.size() != 0){
SubnetsAdapter subnetsAdapter = new SubnetsAdapter(getActivity(),jsonList);
recyclerView.setAdapter(subnetsAdapter);
}else {
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Retrieving data from Server");
pDialog.show();
}
}
});
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((Stackerz) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
//try {
// mListener = (OnFragmentInteractionListener) activity;
//} catch (ClassCastException e) {
// throw new ClassCastException(activity.toString()
// + " must implement OnFragmentInteractionListener");
//}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
And this is the JSON Parser class:
public class SubnetsParser extends Activity{
public static final String NAME = "name";
public static final String GW = "gw";
public static final String CIDR = "cidr";
public static final String ID = "id";
public String authToken;
public String neutronURL;
public static SubnetsParser parser = null;
public static OnJSONLoaded mListener;
public static void setOnJSONLoadedListener(OnJSONLoaded listener) {
mListener = listener;
}
public interface OnJSONLoaded {
void onJsonLoaded(ArrayList<HashMap<String, String>> list);
}
public static SubnetsParser shared(){
if (parser == null){
parser = new SubnetsParser();
}
return parser ;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static ArrayList<HashMap<String, String>> parseJSON(String subnetsJSON){
ArrayList<HashMap<String, String>> jsonList = new ArrayList<HashMap<String, String>>();
try {
Subnets subnets = new Subnets();
JSONObject subnet = new JSONObject(subnetsJSON);
JSONArray subnetobj = subnet.getJSONArray("subnets");
for (int i = 0; i < subnetobj.length(); i++) {
JSONObject objsrv = subnetobj.getJSONObject(i);
subnets.setName(objsrv.getString("name"));
subnets.setGw(objsrv.getString("gateway_ip"));
subnets.setCidr(objsrv.getString("cidr"));
subnets.setId(objsrv.getString("id"));
HashMap<String, String> map = new HashMap<String, String>();
map.put(NAME, subnets.getName());
map.put(GW, subnets.getGw());
map.put(CIDR, subnets.getCidr());
map.put(ID, subnets.getId());
jsonList.add(map);
}
} catch (JSONException e) {
Log.d("ErrorInitJSON", e.toString());
e.printStackTrace();
}
Collections.sort(jsonList, new Comparator<HashMap<String, String>>() {
#Override
public int compare(HashMap<String, String> lhs, HashMap<String, String> rhs) {
return (lhs.get("name")).compareToIgnoreCase(rhs.get("name"));
}
});
if (mListener != null) {
mListener.onJsonLoaded(jsonList);
}
return jsonList;
}
}
You can check if it's empty by running:
if (adapter.getItemCount() == 0)
If it's not working it means you haven't Override the getItemCount on your adapter! so make sure it's overrided:
#Override
public int getItemCount() {
return mDataSet.size(); // Where mDataSet is the list of your items
}
Update:
So based on your update this is how you could proceed. In my opinion you just need a callback. You are checking if the list is empty on your onViewCreated. You should, instead, use a callback. Do something like that:
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.supportsPredictiveItemAnimations();
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setClickable(true);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Retrieving data from Server");
pDialog.show();
}
In the class you are using to populate your jsonList, I assume an asynctask or a separate class add this:
private OnJsonLoaded mListener;
public void setOnJsonLoadedListener(OnJsonLoaded listener) {
mListener = listener;
}
public interface OnJsonLoaded {
void onJsonLoaded(ArrayList<HashMap<String, String>> list);
}
now, in the asynctask that populate ur jsonLise or when the json parser finish his job, call the listener:
if (mListener != null) {
mListener.onJsonLoaded(jsonList);
}
In your fragment (the one with NovaAdapter novaAdapter = new NovaAdapter(getActivity(),jsonList); and your recyclerview) add the interface implementation:
classThatParseJson.setOnJsonLoadedListener(new OnJsonLoaded() {
#Override
public void onJsonLoaded(ArrayList<HashMap<String, String>> list) {
if (list.size() != 0) {
NovaAdapter novaAdapter = new NovaAdapter(getActivity(),jsonList);
recyclerView.setAdapter(novaAdapter);
} else {
// Show something like a dialog that the json list is 0 or do whatever you want... here the jsonlist have a count of 0 so it's empty!
}
}
});
the code may containts errors, i written it by hand without using IDE so maybe you have to fix small things but the logic is quite clear!
Update based on your Update 2:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_subnets, container, false);
recyclerView = (RecyclerView)rootView.findViewById(R.id.subnetsRV);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.supportsPredictiveItemAnimations();
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setClickable(true);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
// start json parser here instead of passing to fragment as a bundle
SubnetsParser.parseJSON(yourparams);
}
#Override
public void onJsonLoaded(ArrayList<HashMap<String, String>> list) {
SubnetsParser.setOnJSONLoadedListener(new OnJSONLoaded() {
#Override
public void onJsonLoaded(ArrayList<HashMap<String, String>> list) {
if (list.size() != 0){
SubnetsAdapter subnetsAdapter = new SubnetsAdapter(getActivity(),jsonList);
recyclerView.setAdapter(subnetsAdapter);
}else {
//pDialog = new ProgressDialog(getActivity());
//pDialog.setMessage("Retrieving data from Server");
//pDialog.show();
//Instead of a progressdialog, put here a dialog informing that the list is empty!
}
}
});
}
How is described in https://developer.android.com/training/material/lists-cards.html
The overriden method getItemCount() is invoked by the layout manager.
This is the snippet:
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.length;
}
So to detect if the recyclerView is empty you must request it to your LayoutManager. Example:
if( mLayoutManager.getItemCount() == 0 ){
//Do something
}
I try to getItemCount() of my Adapter but this returns 0, I don't know why it is...
if (adapter.getItemCount() == 0)
doing this worked for me...
You can do it using interface callback:
Create interface
public interface OnAdapterCountListener {
void onAdapterCountListener(int count);
}
Add below variables and methods in adapter
private OnAdapterCountListener onAdapterCountListener;
public void setOnAdapterCountListener(OnAdapterCountListener l) {
onAdapterCountListener = l;
}
Add this line in onCreateViewHolder of your adapter
onAdapterCountListener.onAdapterCountListener(getItemCount());
Finally, call interface in your activity
listAdapter.setOnAdapterCountListener(new OnAdapterCountListener() {
#Override
public void onAdapterCountListener(int count) {
if (count > 0)
adapterEmptyText.setVisibility(View.GONE);
}
});
Create a Class and inherit Recyclerview - Follow the bellowing code
public class RecyclerviewEmpty extends RecyclerView {
private View emptyView;
private final AdapterDataObserver observer = new AdapterDataObserver() {
#Override
public void onChanged() {
checkIfEmpty();
}
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
checkIfEmpty();
}
#Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
checkIfEmpty();
}
};
public RecyclerviewEmpty(#NonNull Context context) {
super(context);
}
public RecyclerviewEmpty(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public RecyclerviewEmpty(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void checkIfEmpty() {
if (emptyView != null && getAdapter() != null) {
final boolean emptyViewVisible = getAdapter().getItemCount() == 0;
emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
setVisibility(emptyViewVisible ? GONE : VISIBLE);
}
}
#Override
public void setAdapter(#Nullable Adapter adapter) {
final Adapter oldAdapter = getAdapter();
if (oldAdapter != null) {
oldAdapter.unregisterAdapterDataObserver(observer);
}
super.setAdapter(adapter);
if (adapter != null) {
adapter.registerAdapterDataObserver(observer);
}
checkIfEmpty();
}
public void setEmptyView(View emptyView) {
this.emptyView = emptyView;
checkIfEmpty();
}
activity_xml - define class name in a 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"
android:background="#drawable/bg_main"
tools:context=".Ui.FavouriteActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<view
android:id="#+id/rv_fav_activity"
class="com.kumar.random.quotes.Views.RecyclerviewEmpty"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="#+id/list_empty1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Empty Favourite"
android:textSize="14sp" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Activity.java
private RecyclerviewEmpty rvFavourite;
private void setUpRv() {
rvFavourite.setEmptyView(emptyView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
MainQuotesAdapter adapter = new MainQuotesAdapter(this, favouriteItem);
rvFavourite.setLayoutManager(layoutManager);
rvFavourite.setAdapter(adapter);
}
Please notes_01:
rvFavourite.setEmptyView(emptyView);
Please Notes_02:
public void setEmptyView(View emptyView) {
this.emptyView = emptyView;
checkIfEmpty();
}
Please Notes_03
<view
android:id="#+id/rv_fav_activity"
class="com.kumar.random.quotes.Views.RecyclerviewEmpty"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I have been trying this code for extracting data from Parse.com, it works great with GridView and ListView. What i want to do is, implement it in a HorizontalListView, for which i use this library. The main issue with this is, the images are loading properly but the list wont scroll at all, where as if i use it normally for anything else, it works fine. I have tried it with loading images from URL's.
ParseFragment.java
public class ParseFragment extends Fragment {
public ParseFragment() {
}
HorizontalListView grid;
List<ParseObject> ob;
GridViewAdapter adapter;
private List<GlowoodList> glowoodList = null;
View rootView;
String button_str;
ParseFile image;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main, container, false);
Bundle bundle = getArguments();
button_str = bundle.getString("button");
Log.e("BUTTON CLICKED", "BUTTON CLICKED: " + button_str);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
Parse.initialize(ParseFragment.this.getActivity(),
"Application_id",
"Client_id");
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
new RemoteDataTask().execute();
}
});
t.start();
return rootView;
}
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
glowoodList = new ArrayList<GlowoodList>();
try {
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
button_str);
query.orderByAscending("position");
ob = query.find();
for (ParseObject country : ob) {
image = (ParseFile) country.get("wallpapers");
GlowoodList map = new GlowoodList();
map.setPhone(image.getUrl());
map.setName((String) country.get("Name"));
glowoodList.add(map);
}
} catch (ParseException e) {
Log.e("ParseException", "parse: " + e);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
grid = (HorizontalListView) rootView.findViewById(R.id.grid);
adapter = new GridViewAdapter(ParseFragment.this.getActivity(),
glowoodList);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.e("URL", "URL" + image.getUrl());
}
});
}
}
}
fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.parsedotcom.MainActivity$PlaceholderFragment" >
<com.meetme.android.horizontallistview.HorizontalListView
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawHorizontalTrack="true"
></com.meetme.android.horizontallistview.HorizontalListView>
</RelativeLayout>
GridViewAdapter.java
public class GridViewAdapter extends BaseAdapter {
Context context;
LayoutInflater inflater;
ImageLoader image;
private List<GlowoodList> glowoodList = null;
private ArrayList<GlowoodList> arraylist;
public GridViewAdapter(Context context, List<GlowoodList> glowoodList) {
super();
this.context = context;
this.glowoodList = glowoodList;
this.arraylist = new ArrayList<GlowoodList>();
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.arraylist.addAll(glowoodList);
image = new ImageLoader(context);
}
public class ViewHolder{
ImageView phone;
TextView text;
}
#Override
public int getCount() {
return glowoodList.size();
}
#Override
public Object getItem(int position) {
return glowoodList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView==null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.grid_images, null);
holder.phone = (ImageView)convertView.findViewById(R.id.phone);
holder.text = (TextView)convertView.findViewById(R.id.text);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
image.DisplayImage(glowoodList.get(position).getPhone(),holder.phone);
holder.text.setText(glowoodList.get(position).getName());
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString("phone", glowoodList.get(position).getPhone());
bundle.putString("name", glowoodList.get(position).getName());
Log.e("BUNDLE POSITION", "BUNDLE POSITION:"+bundle);
}
});
return convertView;
}
}
Can someone please help??! The HorizontalListView does not scroll at all !!!
Thank you