Related
I am displaying a userlist and I am using serachview in my actionbar to search. When I am using the searchView in activity, it works fine but when I use it for fragment, searchview doesn't work. It does not search in the listview.
Below is my code.
UserListFragment.java
public class UsersListFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
Activity activity;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private static final String TAG = "UsersListFragment";
private OnFragmentInteractionListener mListener;
private ListView listView;
private List<UserData> users;
private CustomAdapter adapter;
SharedPreferences.Editor preferenceEditor;
Timer myTimer;
View view;
ActionBar actionBar;
private static final String PREFRENCES_NAME = "setPreferences";
private ProgressDialog progressBar;
String partnerKeyValue;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment UsersListFragment.
*/
// TODO: Rename and change types and number of parameters
public static UsersListFragment newInstance(String param1, String param2) {
UsersListFragment fragment = new UsersListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressBar = new ProgressDialog(getActivity());
progressBar.setCancelable(false);
progressBar.setMessage("Loading...");
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressBar.setProgress(0);
Log.i(TAG, "UsersListFragment onCreate");
users = new ArrayList<>();
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
SharedPreferences preferenceSettings = getActivity().getSharedPreferences(PREFRENCES_NAME,Context.MODE_PRIVATE);
preferenceEditor = preferenceSettings.edit();
preferenceEditor.putString("refresh","userlistview");
preferenceEditor.commit();
FirebaseUtil uts = new FirebaseUtil(getContext());
uts.startListeningNotification(Global.getInstance().ownerId, new CallBack() {
#Override
public void onCallback(Map<String, Object> response, String Success) {
Log.i(TAG, Success);
setHasOptionsMenu(true);
String partnerKey = (String) response.get("key");
if (partnerKey != null) {
Map<String, Object> typeCheck = (Map<String, Object>) response.get("value");
String type = (String) typeCheck.get("type");
if (type.equals("chat")) {
String key1 = Global.getInstance().ownerId;
String key2 = partnerKey;
partnerKeyValue = partnerKey;
if (key2 != null) {
String currentPartner = Global.getInstance().partnerId;
if (currentPartner.length() > 0) {
if (currentPartner.equals(partnerKey)) {
} else {
Global.getInstance().unreadMessageUsers.add(partnerKey);
}
Global.getInstance().unreadMessageUsers.add(partnerKey);
} else {
}
}
}
}
}
});
}
#Override
public void onStart() {
super.onStart();
Log.i(TAG, "UsersListFragment onStart");
}
#Override
public void onResume() {
super.onResume();
Log.i(TAG, "UsersListFragment onResume");
}
#Override
public void onPause() {
super.onPause();
Log.i(TAG, "UsersListFragment onStart");
}
#Override
public void onStop() {
super.onStop();
Log.i(TAG, "UsersListFragment onStop");
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
#Override
public void onDestroy() {
super.onDestroy();
FirebaseUtil util = new FirebaseUtil(getContext());
util.updateUserStatus(Global.getInstance().ownerId, "4");
Log.i(TAG, "UsersListFragment onDestroy");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if(actionBar!=null) {
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setLogo(R.drawable.ic_logo);
ColorDrawable colorDrawable = new ColorDrawable(Color.parseColor("#006EAD"));
actionBar.setBackgroundDrawable(colorDrawable);
}
Toast.makeText(getActivity(), String.valueOf( Global.getInstance().unreadMessageUsers.size()) , Toast.LENGTH_SHORT).show();
int vd = users.size();
view = inflater.inflate(R.layout.fragment_userslist, container, false);
listView = (ListView) view.findViewById(R.id.userdisplay);
adapter = new CustomAdapter(getActivity(),R.layout.program_list, users );
listView.setAdapter(adapter);
if (users.size()==0){
usersList();
}else {
adapter.notifyDataSetChanged();
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
UserData data = users.get(position);
Global.getInstance().someData = data.getId();
Global.getInstance().partnerId = data.getId();
int i = 0;
for (Iterator<String> iter = Global.getInstance().unreadMessageUsers.iterator(); iter.hasNext(); ) {
String element = iter.next();
if (element.equals(data.getId().toString())) {
iter.remove();
}
}
data.setUnreadMessageCount(0);
users.remove(position);
users.add(position, data);
Toast.makeText(getActivity().getApplicationContext(),String.valueOf(Global.getInstance().unreadMessageUsers.size()),Toast.LENGTH_LONG).show();
Fragment fragmentOne = new ChatFragment();
android.support.v4.app.FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
Bundle args = new Bundle();
args.putString(ChatFragment.DATA_RECEIVE, data.getName());
fragmentOne .setArguments(args);
ft.addToBackStack(null);
ft.replace(R.id.framecontainerMain, fragmentOne).commit();
}
});
// Inflate the layout for this fragment
return view;
}
public void usersList () {
SharedPreferences preferenceSettings = getActivity().getSharedPreferences(PREFRENCES_NAME,Context.MODE_PRIVATE);
preferenceEditor = preferenceSettings.edit();
//get the data from userlist api
final String URL = "url";
String token = preferenceSettings.getString("authToken","");
final String userId = preferenceSettings.getString("userId","");
HashMap<String, String> params = new HashMap<String, String>();
params.put("user_id",userId);
params.put("auth_token",token);
progressBar.show();
JsonObjectRequest myRequest = new JsonObjectRequest(Request.Method.POST, URL,new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i(TAG, "onResponse:" +response);
String success = null;
try {
success = response.getString("success");
} catch (JSONException e) {
e.printStackTrace();
}
if(success == "true") {
JSONArray Array = null;
try {
//get the users
} else {
users.add(data);
}
}
Log.i(TAG, "arraylist");
adapter.notifyDataSetChanged();
onlineUsers();
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, 5000);
progressBar.dismiss();
} catch (JSONException e) {
e.printStackTrace();
}
JSONObject Obj;
} else {
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressBar.dismiss();
VolleyLog.e("Error: ", error.getMessage());
Log.i(TAG, "onErrorResponse:" +error.networkResponse);
}
});
ApplicationController.getInstance().addToRequestQueue(myRequest);
myRequest.setRetryPolicy(new DefaultRetryPolicy(
5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
public void sortingArray(){
if (users.size()>0) {
synchronized (this) {
if (Global.getInstance().unreadMessageUsers.size() > 0) {
System.out.println("\nExample 3 - Count all with Map");
Map<String, Integer> map = new HashMap<String, Integer>();
for (String temp : Global.getInstance().unreadMessageUsers) {
Integer count = map.get(temp);
map.put(temp, (count == null) ? 1 : count + 1);
}
System.out.println("\nSorted Map");
Map<String, Integer> unreadCount = new TreeMap<String, Integer>(map);
for (String key : unreadCount.keySet()) {
int count_unread = unreadCount.get(key);
int i = 0;
for (UserData obj : users) {
UserData user = obj;
if (user.getId().equals(key)) {
user.setUnreadMessageCount(count_unread);
users.remove(i);
users.add(i, user);
break;
}
i++;
}
}
}
synchronized (this) {
if (Global.getInstance().userStatus.size() > 0) {
try {
for (Object dict : Global.getInstance().userStatus) {
Map<String, Object> val = (Map<String, Object>) dict;
String key = val.keySet().iterator().next();
val.get(key).toString().trim();
int statusValue;
if (val.get(key).toString().equals("")) {
statusValue = 4;
} else {
statusValue = Integer.valueOf(val.get(key).toString());
}
int i = 0;
for (UserData obj : users) {
UserData user = obj;
if (user.getId().equals(key)) {
user.setOnlineStatus(statusValue);
users.remove(i);
users.add(i, user);
break;
}
i++;
}
}
}catch (ConcurrentModificationException e){
e.printStackTrace();
}
}
}
Log.i(TAG, users.get(0).getName());
if (users.size() > 0) {
Collections.sort(users, new Comparator<UserData>() {
#Override
public int compare(UserData o1, UserData o2) {
if (o1.getOnlineStatus() > o2.getOnlineStatus()) {
return 1;
} else if (o1.getOnlineStatus() < o2.getOnlineStatus()) {
return -1;
} else {
return 0;
}
}
});
}
if (users.size() > 0) {
Collections.sort(users, new Comparator<UserData>() {
#Override
public int compare(UserData o1, UserData o2) {
if (o1.getUnreadMessageCount() > o2.getUnreadMessageCount()) {
return -1;
} else if (o1.getUnreadMessageCount() < o2.getUnreadMessageCount()) {
return 1;
} else {
return 0;
}
}
});
Global.getInstance().userStatus.clear();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(), "any mesage", Toast.LENGTH_LONG).show();
adapter.notifyDataSetChanged();
}
});
}
}
}
}
public void TimerMethod() {
synchronized(this) {
SharedPreferences preferenceSettings = getActivity().getSharedPreferences("setPreferences", Context.MODE_PRIVATE);
String checkView = preferenceSettings.getString("refresh", "");
if (checkView.equals("userlistview")) {
if (Global.getInstance().userStatus.size() > 0) {
sortingArray();
}
} else {
preferenceEditor = preferenceSettings.edit();
preferenceEditor.putString("refresh", "userlistview");
preferenceEditor.commit();
if (Global.getInstance().unreadMessageUsers.size() > 0){
sortingArray();
}
}
}
}
public void onlineUsers (){
String value;
for (UserData data : users) {
value = data.getId();
FirebaseUtil online = new FirebaseUtil(getContext());
online.onlineUsers(value, new CallBack() {
#Override
public void onCallback(Map<String, Object> response, String Success) {
if (response == null) {
} else {
Global.getInstance().userStatus.add(response);
}
}
});
}
}
#Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
inflater.inflate(R.menu.menu_userlist,menu);
MenuItem item = menu.findItem(R.id.menuSearch);
SearchView searchView = (SearchView)item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
super.onCreateOptionsMenu(menu,inflater);
}
private void logoutUser(){
Intent I = new Intent(getActivity(), LoginActivity.class);
startActivity(I);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menuSearch :
return true;
case R.id.menuLogout :
logoutUser();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
String val = "'";
mListener.onFragmentInteraction(val);
}
}
public void initlizeval(Context context) {
mListener = (OnFragmentInteractionListener) context;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
myTimer.cancel();
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
void onFragmentInteraction(String val);
}
}
menu_userlist.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/menuSearch"
android:title="#string/search"
android:icon="#drawable/ic_search"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always">
</item>
<item android:id="#+id/menuLogout"
android:title="#string/logout"
android:icon="#drawable/ic_logout"
android:tint="#android:color/white"
app:showAsAction="always">
</item>
</menu>
CustomAdapter.java
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class CustomAdapter extends ArrayAdapter<UserData> {
private Activity activity;
private List<UserData> messages;
public CustomAdapter(Activity context, int resource, List<UserData> objects) {
super(context, resource, objects);
this.activity = context;
this.messages = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
packagename.CustomAdapter.ViewHolder holder;
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
int layoutResource = 0; // determined by view type
UserData data = getItem(position);
int viewType = getItemViewType(position);
layoutResource = R.layout.program_list;
if (convertView != null) {
holder = (com.your.package.CustomAdapter.ViewHolder) convertView.getTag();
} else {
convertView = inflater.inflate(layoutResource, parent, false);
holder = new com.your.package.CustomAdapter.ViewHolder(convertView);
convertView.setTag(holder);
}
//set message content
holder.msg.setText(data.getName());
holder.id = data.geId();
holder.roleMsg.setText(data.getRole());
return convertView;
}
#Override
public int getViewTypeCount() {
// return the total number of view types. this value should never change
// at runtime
return 2;
}
#Override
public int getItemViewType(int position) {
// return a value between 0 and (getViewTypeCount - 1)
return position % 2;
}
private class ViewHolder {
private TextView msg;
private String id;
private TextView roleMsg;
public ViewHolder(View v) {
msg = (TextView) v.findViewById(R.id.textView1);
roleMsg = (TextView) v.findViewById(R.id.textView2);
}
}
}
HomeActivity.java
public class HomeActivity extends AppCompatActivity implements UsersListFragment.OnFragmentInteractionListener {
private UsersListFragment mItemsFragment;
private ChatFragment mFragmentOne;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
VideoFragment fragmentTwo ;
LinearLayout layout1 = (LinearLayout) findViewById(R.id.framecontainer);
layout1.setVisibility(View.VISIBLE);
LinearLayout layout2 = (LinearLayout) findViewById(R.id.framecontainerTab);
layout2.setVisibility(View.VISIBLE);
mItemsFragment = new UsersListFragment();
mItemsFragment.initlizeval(this);
android.support.v4.app.FragmentTransaction fts = getSupportFragmentManager().beginTransaction();
fts.add(R.id.framecontainer, mItemsFragment).commit();
//Instantiate some stuff here like view components
Fragment fragmentOne = new ChatFragment();
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.framecontainerTab, fragmentOne).commit();
}else{
LinearLayout layout1 = (LinearLayout) findViewById(R.id.framecontainer);
layout1.setVisibility(View.GONE);
LinearLayout layout2 = (LinearLayout) findViewById(R.id.framecontainerTab);
layout2.setVisibility(View.GONE);
layout2.removeAllViews();
mItemsFragment = new UsersListFragment();
mItemsFragment.initlizeval(this);
setFragment(mItemsFragment);
}
}
public void setFragment(Fragment frag)
{
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
}
public void attemptLogin1() {
String test = "one";
String tested = "fail";
}
#Override
public void onFragmentInteraction(String uri) {
LinearLayout layout1 = (LinearLayout) findViewById(R.id.framecontainer);
layout1.setVisibility(View.GONE);
LinearLayout layout2 = (LinearLayout)findViewById(R.id.framecontainerTab);
layout2.setVisibility(View.GONE);
findViewById(R.id.framecontainerVideo);
Toast.makeText(getApplicationContext(), "bullet", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void onBackPressed() {
super.onBackPressed();
Fragment fragmentOne = new ChatFragment();
LinearLayout layout1 = (LinearLayout) findViewById(R.id.framecontainer);
layout1.setVisibility(View.VISIBLE);
LinearLayout layout2 = (LinearLayout) findViewById(R.id.framecontainerTab);
layout2.setVisibility(View.VISIBLE);
}
#Override
protected void onStart() {
super.onStart();
getDelegate().onStart();
}
}
I have written setHasOptionsMenu(true); in onCreate of UserFragment.java
The logout functionality works fine but the search isn't working.
I have tried various options given on Stackoverflow as well as from other resource, but nothing worked. :(
Any help is appreciated.
Thanks in advance.
Create Constructor in your fragment. Pass Context object inside fragment constructor.which allows your activity as global access.
Remove this line and it will work
case R.id.menuSearch:
return true;
I have fragment with Asynctask class which needs to Re-Run the Asynctask from my Recyclerview adapter class.
Note : I want re run asynctask inside of viewHolder.buttonnext.setOnClickListener(new View.OnClickListener() { in onBindViewHolder and when use this line.
new maghalat.GetContacts().execute(); //maghalt is name of fragment contain GetContacts asynctask function
Give me red line under this line without any suggestion
this is my adapter :
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private Context context;
List<jsonContent> jcontent;
public DataAdapter(Context context, List<jsonContent> jcontent) {
this.context=context;
this.jcontent=jcontent;
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view ;
if(i == R.layout.card_row) {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_row, viewGroup, false);
}else {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.button_card, viewGroup, false);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder viewHolder,int i) {
if(i == jcontent.size()) {
viewHolder.buttonnext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//try This
((maghalat )context).asyncRun();
}
});
viewHolder.buttonprev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "pre", Toast.LENGTH_SHORT).show();
}
});
viewHolder.go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.pages.setText(Integer.toString(jcontent.get(i-1).pages));
}
else {
viewHolder.title.setText(jcontent.get(i).title);
Picasso.with(context).load(jcontent.get(i).imgurl).resize(300, 400).into(viewHolder.imageView);
}
}
#Override
public int getItemCount() {
return jcontent.size()+1;
}
#Override
public int getItemViewType(int position) {
return (position == jcontent.size()) ? R.layout.button_card : R.layout.card_row;
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView title,pages;
private ImageView imageView;
private Button buttonnext,buttonprev,go;
private CardView cardView;
private EditText editText;
public ViewHolder(final View view) {
super(view);
title = (TextView)view.findViewById(R.id.post_title);
imageView=(ImageView)view.findViewById(R.id.img);
buttonnext =(Button)view.findViewById(R.id.next);
buttonprev=(Button)view.findViewById(R.id.prev);
go=(Button)view.findViewById(R.id.go);
editText=(EditText)view.findViewById(R.id.et_go_page);
cardView=(CardView)view.findViewById(R.id.cvv);
pages=(TextView)view.findViewById(R.id.number_pages);
}
}
}
this is my fragment :
public class maghalat extends Fragment {
private RecyclerView recyclerView;
private DataAdapter adapter;
private View myFragmentView;
private String TAG = MainActivity.class.getSimpleName();
private ProgressDialog pDialog;
private int numpage=0;
public int sag;
private String url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(sag)+"/?json=get_posts";
List<jsonContent> listcontent=new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.maghalat, container, false);
if(isNetworkConnected()) {
asyncRun();
}else
{
Toast.makeText(getActivity().getApplicationContext(), "دستگاه شما به اینترنت متصل نیست!", Toast.LENGTH_LONG).show();
}
return myFragmentView;
}
public void asyncRun(){
new GetContacts().execute();
}
public class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
sag=numpage+1;
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
int id=jsonObj.getInt("pages");
JSONArray posts = jsonObj.getJSONArray("posts");
for (int i = 0; i < posts.length(); i++) {
JSONObject c = posts.getJSONObject(i);
jsonContent jsonContent=new jsonContent();
jsonContent.title=c.getString("title");
//img
JSONObject post_img=c.getJSONObject("thumbnail_images");
for (int j=0;j<post_img.length();j++)
{
JSONObject v=post_img.getJSONObject("mom-portfolio-two");
jsonContent.imgurl=v.getString("url");
}
jsonContent.pages=id;
listcontent.add(jsonContent);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
pDialog.dismiss();
recyclerView=(RecyclerView)myFragmentView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
adapter=new DataAdapter(getActivity(),listcontent);
recyclerView.setAdapter(adapter);
}
}
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
// There are no active networks.
return false;
} else
return true;
}
}
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private Context context;
List<jsonContent> jcontent;
private maghalat fragment;
public DataAdapter(Context context, List<jsonContent> jcontent, maghalat frag) {
this.context=context;
this.jcontent=jcontent;
this.fragment = frag;
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view ;
if(i == R.layout.card_row) {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_row, viewGroup, false);
}else {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.button_card, viewGroup, false);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder viewHolder,int i) {
if(i == jcontent.size()) {
viewHolder.buttonnext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//try This
(fragment).asyncRun();
}
});
viewHolder.buttonprev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "pre", Toast.LENGTH_SHORT).show();
}
});
viewHolder.go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.pages.setText(Integer.toString(jcontent.get(i-1).pages));
}
else {
viewHolder.title.setText(jcontent.get(i).title);
Picasso.with(context).load(jcontent.get(i).imgurl).resize(300, 400).into(viewHolder.imageView);
}
}
#Override
public int getItemCount() {
return jcontent.size()+1;
}
#Override
public int getItemViewType(int position) {
return (position == jcontent.size()) ? R.layout.button_card : R.layout.card_row;
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView title,pages;
private ImageView imageView;
private Button buttonnext,buttonprev,go;
private CardView cardView;
private EditText editText;
public ViewHolder(final View view) {
super(view);
title = (TextView)view.findViewById(R.id.post_title);
imageView=(ImageView)view.findViewById(R.id.img);
buttonnext =(Button)view.findViewById(R.id.next);
buttonprev=(Button)view.findViewById(R.id.prev);
go=(Button)view.findViewById(R.id.go);
editText=(EditText)view.findViewById(R.id.et_go_page);
cardView=(CardView)view.findViewById(R.id.cvv);
pages=(TextView)view.findViewById(R.id.number_pages);
}
}
}
Your Fragment
public class maghalat extends Fragment {
private RecyclerView recyclerView;
private DataAdapter adapter;
private View myFragmentView;
private String TAG = MainActivity.class.getSimpleName();
private ProgressDialog pDialog;
private int numpage=0;
public int sag;
private String url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(sag)+"/?json=get_posts";
List<jsonContent> listcontent=new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.maghalat, container, false);
if(isNetworkConnected()) {
asyncRun();
}else
{
Toast.makeText(getActivity().getApplicationContext(), "دستگاه شما به اینترنت متصل نیست!", Toast.LENGTH_LONG).show();
}
return myFragmentView;
}
public void asyncRun(){
new GetContacts().execute();
}
public class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
sag=numpage+1;
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
int id=jsonObj.getInt("pages");
JSONArray posts = jsonObj.getJSONArray("posts");
for (int i = 0; i < posts.length(); i++) {
JSONObject c = posts.getJSONObject(i);
jsonContent jsonContent=new jsonContent();
jsonContent.title=c.getString("title");
//img
JSONObject post_img=c.getJSONObject("thumbnail_images");
for (int j=0;j<post_img.length();j++)
{
JSONObject v=post_img.getJSONObject("mom-portfolio-two");
jsonContent.imgurl=v.getString("url");
}
jsonContent.pages=id;
listcontent.add(jsonContent);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
pDialog.dismiss();
recyclerView=(RecyclerView)myFragmentView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
adapter=new DataAdapter(getActivity(),listcontent,maghalat.this);
recyclerView.setAdapter(adapter);
}
}
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
// There are no active networks.
return false;
} else
return true;
}
}
I've tried to find out how to get selected id of the ratingBar in ListView on net, but almost of them using ListViewAdapter or RatingAdapter on another class. I don't know how to do, because I do not yet know about it, so all my classes declared in MainActivity including ListView.
I have a TextView and RatingBar on each list in ListView,
but the issue is how to send each list of RatingBar that already fills into server without create a new class of ListViewAdapter or RatingAdapter??
here is my full code how it's work to display the TextView and RatingBar on each list:
public class Pertanyaan extends AppCompatActivity {
private String TAG = Pertanyaan.class.getSimpleName();
private ProgressDialog pDialog;
private ListView lv;
private Button kirim;
private RatingBar rate;
ArrayList<HashMap<String, String>> contactList;
#Override
public void onBackPressed() {
super.onBackPressed();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pertanyaan);
contactList = new ArrayList<>();
TextView textdosen=(TextView)findViewById(R.id.dosen);
TextView textmatkul=(TextView)findViewById(R.id.matkul);
final TextView txtrate=(TextView)findViewById(R.id.txtrating);
kirim = (Button)findViewById(R.id.btn);
rate=(RatingBar)findViewById(R.id.rating);
Bundle b=getIntent().getExtras();
String dosen=b.getString("dosen");
String matkul=b.getString("matkul");
textdosen.setText(dosen);
textmatkul.setText(matkul);
lv = (ListView) findViewById(R.id.list);
new GetContacts().execute();
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(Pertanyaan.this);
pDialog.setMessage("Menampilkan Pertanyaan...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String url = "http://flix.16mb.com/send_data.php";
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONArray jsonObj = new JSONArray(jsonStr);
// looping through All Contacts
for (int i = 0; i < jsonObj.length(); i++) {
JSONObject c = jsonObj.getJSONObject(i);
String id = c.getString("id");
String ask = c.getString("ask");
HashMap<String, String> pertanyaans = new HashMap<>();
pertanyaans.put("id", id);
pertanyaans.put("ask", ask);
contactList.add(pertanyaans);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
Pertanyaan.this, contactList,
R.layout.list_pertanyaan, new String[]{"ask", "id"}, new int[]{R.id.ask, R.id.txtid});
lv.setAdapter(adapter);
}
}
}
can someone give me a hint what should i do?
Ok here is a sample application so that it should give you some help:
First of all you need to create a CustomAdapter because SimpleAdapter has limitations. Secondly you need to use RecyclerView instead of ListView. After that you need to register a click event when the user clicks on the list that you have made. For those things we come with the following:
The Model of the list:
public class CustomList {
private String id, ask;
public CustomList(String id, String ask) {
this.id = id;
this.ask = ask;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAsk() {
return ask;
}
public void setAsk(String ask) {
this.ask = ask;
}
}
then the layout for each list item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:padding="15dp"
android:layout_height="wrap_content">
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/id_text"
android:layout_weight="4" />
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/ask_text"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
then the layout for RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="kostas.testexample.com.testexample.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
then the custom adapter:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder>{
private List<CustomList> items;
private Context context;
public CustomAdapter(List<CustomList> items, Context context){
this.items = items;
this.context = context;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item, parent, false);
return new CustomViewHolder(v);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
holder.itemId.setText(items.get(position).getId());
holder.itemAsk.setText(items.get(position).getAsk());
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
class CustomViewHolder extends RecyclerView.ViewHolder {
TextView itemId;
TextView itemAsk;
CustomViewHolder(View itemView) {
super(itemView);
itemId = (TextView)itemView.findViewById(R.id.id_text);
itemAsk = (TextView)itemView.findViewById(R.id.ask_text);
}
}
}
then you add them all up in MainActivity like this:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private URL url;
private HttpURLConnection httpURLConnection;
private CustomAdapter customAdapter;
private ProgressDialog pDialog;
private String id, ask;
private List<CustomList> customList = new ArrayList<>();
private StringBuilder jsonResult;
private JSONObject jsonChildNode;
private JSONArray jsonResponse;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.myRecyclerView);
layoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);
accessWebService();
clickEvent();
}
private void clickEvent() {
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(MainActivity.this, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this, "Item Clicked at position: " + position + " with id: " + customList.get(position).getId() + " and ask is: " + customList.get(position).getAsk(), Toast.LENGTH_SHORT).show();
}
}));
}
public class JsonReadTask extends AsyncTask<String , Void, List<CustomList>> {
public JsonReadTask() {
super();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setIndeterminate(true);
pDialog.setMessage("Please Wait");
pDialog.setCancelable(false);
pDialog.setInverseBackgroundForced(true);
// pDialog.show();
}
#Override
protected List<CustomList> doInBackground(String... params) {
try {
url = new URL(params[0]);
httpURLConnection =(HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream in = new BufferedInputStream(httpURLConnection.getInputStream());
jsonResult = inputStreamToString(in, MainActivity.this);
jsonResponse = new JSONArray(jsonResult.toString());
for (int i = 0; i < jsonResponse.length(); i++) {
jsonChildNode = jsonResponse.getJSONObject(i);
id = jsonChildNode.optString("id");
ask = jsonChildNode.optString("ask");
customList.add(new CustomList(id, ask));
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return customList;
}
#Override
protected void onPostExecute(List<CustomList> customList) {
if(customList == null){
Log.d("ERORR", "No result to show.");
return;
}
ListDrawer(customList);
pDialog.dismiss();
}
}
public static StringBuilder inputStreamToString(InputStream is, Activity activity) {
String rLine;
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
} catch (Exception e) {
activity.finish();
}
return answer;
}
private void ListDrawer(List<CustomList> customList) {
customAdapter = new CustomAdapter(customList, MainActivity.this);
customAdapter.notifyDataSetChanged();
recyclerView.setAdapter(customAdapter);
}
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
task.execute("http://flix.16mb.com/send_data.php");
}
}
and then you need the customListener for RecyclerView
public class RecyclerItemClickListener implements OnItemTouchListener {
private OnItemClickListener mListener;
private OnLongItemClickListener mLongListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
interface OnLongItemClickListener{
boolean onLongItemClicked(int position);
}
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
public RecyclerItemClickListener(Context context, OnLongItemClickListener listener) {
mLongListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.OnGestureListener() {
#Override
public boolean onDown(MotionEvent e) {
return false;
}
#Override
public void onShowPress(MotionEvent e) {
}
#Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
#Override
public void onLongPress(MotionEvent e) {
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
which produces the following result:
but do not forget to add to build.gradle(Module: app) the following:
compile 'com.android.support:recyclerview-v7:25.0.1'
and in your Manifest.xml the permission:
<uses-permission android:name="android.permission.INTERNET"/>
Hope it helps and give you a hint on how to do stuff!!!
I'm trying to show custom progressbar using this 3rd party library in 2 fragments of TabLayout. I'm displaying the progressbar while in background I'm doing volley stringrequest. Problem is the progressbar is not hiding even after the result gets loaded from web service. This problem does not occurs when I use regular progressdialog with TabLayout. Although this custom progressbar works fine in normal layout, its not working in TabLayout. Is there any particular reason for this? Thanks.
// custom_progress_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#android:color/transparent"
android:orientation="vertical">
<com.wang.avi.AVLoadingIndicatorView
android:id="#+id/progress_bar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:visibility="gone"
app:indicator="BallClipRotatePulse"
app:indicator_color="#android:color/darker_gray"/>
</RelativeLayout>
// One of the fragment of TabLayout
public class FirstFragment extends Fragment {
private TextView tv1;
private CShowProgress cShowProgress;
private static final String CUSTOMERS_INFO = "My API";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.first, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv1 = (TextView)view.findViewById(R.id.tv1);
cShowProgress = CShowProgress.getInstance();
showCustomersDetails();
}
private void showCustomersDetails() {
cShowProgress.showProgress(getActivity());
StringRequest stringRequest = new StringRequest(Request.Method.POST, CUSTOMERS_INFO,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
cShowProgress.hideProgress(); // THIS DOESNOT WORK AS PROGRESSBAR STILL SHOWS
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("aboutuser");
for(int i=0; i<jsonArray.length(); i++){
JSONObject obj = jsonArray.getJSONObject(i);
String str1 = "Contact:" + obj.getString("primary_contact");
String str2 = "EMail:" + obj.getString("email");
String total = str1 + "\n" + str2;
tv1.setText(total);
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "VolleyError" + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("spaid", "145");
params.put("customer_id", "64");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
}
}
//Custom Class for 3rd party library of progressbar
public class CShowProgress {
public static CShowProgress s_m_oCShowProgress;
public static Context m_Context;
public Dialog m_Dialog;
public CShowProgress(Context m_Context) {
this.m_Context = m_Context;
}
public static CShowProgress getInstance() {
if (s_m_oCShowProgress == null) {
s_m_oCShowProgress = new CShowProgress(m_Context);
}
return s_m_oCShowProgress;
}
public void showProgress(Context m_Context) {
m_Dialog = new Dialog(m_Context);
m_Dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
m_Dialog.setContentView(R.layout.custom_progress_layout);
m_Dialog.findViewById(R.id.progress_bar).setVisibility(View.VISIBLE);
m_Dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
m_Dialog.setCancelable(true);
m_Dialog.setCanceledOnTouchOutside(true);
m_Dialog.show();
}
public void hideProgress() {
if (m_Dialog != null) {
m_Dialog.dismiss();
m_Dialog = null;
}
}
}
try this,
public void hideProgress() {
if (m_Dialog != null) {
m_Dialog.setVisible(View.GONE);
m_Dialog = null;
}
}
OR in your onResponse()
cShowProgress.setVisible(View.GONE);
I made some changes in my custom progress dialog class and now it works...
public class CShowProgress extends Dialog{
private Dialog mpd = null;
private LayoutInflater inflater = null;
public CShowProgress(Context context) {
super(context)
}
public void showProgress(Context context) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View view = inflater.inflate(R.layout.custom_progress_layout, null);
mpd = new Dialog(context);
mpd.requestWindowFeature(Window.FEATURE_NO_TITLE);
mpd.setContentView(view);
mpd.findViewById(R.id.progress_bar).setVisibility(View.VISIBLE);
mpd.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
mpd.setCancelable(true);
mpd.show();
}
public void hideProgress() {
if (mpd != null) {
if (mpd.isShowing()){
mpd.dismiss();
}
}
}
}
I know that this question was asked many times before, but i'm confused why sometimes the data is loaded and sometimes data isn't loaded once i get to the end of list. Also when i go fast scrolling through the list, and the new data has been loaded, but immediately it returns me to the first item in list and remove all new loaded items from the next page from server. So that is the second problem and the third problem is that when i load items using SwipeRefreshLayout, i'm also not getting new items when i reach the end of the list.
I have implemented this in my project: https://gist.github.com/ssinss/e06f12ef66c51252563e
list.setLayoutManager(manager);
list.setEmptyView(emptyView);
list.setItemAnimator(new DefaultItemAnimator());
list.setAdapter(mAdapter);
loadJokes(1);
list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
#Override
public void onLoadMore(final int current_page) {
loadMoreJokes(current_page);
}
});
Here is the method where i'm loading more items from server:
private void loadMoreJokes(int current_page) {
StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + current_page,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
hideDialog();
try {
JSONObject object = new JSONObject(response);
boolean error = object.getBoolean("error");
JSONArray jokes = object.getJSONArray("jokes");
if (!error) {
for (int i = 0; i < jokes.length(); i++) {
JSONObject object1 = jokes.getJSONObject(i);
Joke joke = new Joke();
joke.setId(object1.optInt("id"));
joke.setLikes(object1.optInt("likes"));
joke.setComments(object1.optInt("comments"));
joke.setJoke(object1.optString("joke"));
joke.setCreatedAt(object1.optString("created_at"));
joke.setName(object1.optString("user_name"));
joke.setImagePath(object1.optString("image_path"));
joke.setFacebookUserId(object1.optString("facebook_user_id"));
joke.setCategory(object1.optString("category"));
mJokes.add(joke);
}
menu.showMenu(true);
}
// Notify adapter that data has changed
mAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideDialog();
Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
AppController.getInstance().addToRequestQueue(request);
}
And here is the method where i'm loading first visible items when someone launch the app:
private void loadJokes(int page) {
pDialog.setMessage("Loading..");
showDialog();
StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + page,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
mJokes.clear();
hideDialog();
try {
JSONObject object = new JSONObject(response);
boolean error = object.getBoolean("error");
JSONArray jokes = object.getJSONArray("jokes");
if (!error) {
for (int i = 0; i < jokes.length(); i++) {
JSONObject object1 = jokes.getJSONObject(i);
Joke joke = new Joke();
joke.setId(object1.optInt("id"));
joke.setLikes(object1.optInt("likes"));
joke.setComments(object1.optInt("comments"));
joke.setJoke(object1.optString("joke"));
joke.setCreatedAt(object1.optString("created_at"));
joke.setName(object1.optString("user_name"));
joke.setImagePath(object1.optString("image_path"));
joke.setFacebookUserId(object1.optString("facebook_user_id"));
joke.setCategory(object1.optString("category"));
mJokes.add(joke);
}
menu.showMenu(true);
}
// Notify adapter that data has changed
mAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideDialog();
menu.showMenu(true);
Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
AppController.getInstance().addToRequestQueue(request);
}
And this is onRefresh() method:
#Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
refreshItems();
}
}, 5000);
}
private void refreshItems() {
loadJokes(1);
mSwipeRefreshLayout.setRefreshing(false);
}
If i need to post more code, let me know. I really need to solve this problem as soon as i can. So again, the problems are the following:
When fast scrolling through the list, new items are being loaded, but immediately after that it returns me to the beginning of the list and when i go to the end of list again, load more doesn't respond.
After refreshing the list with SwipRefreshLayout, also scrolling doesn't respond at the end.
Note: The scrolling and loading new items is working only if i go slowly through the list and if i didn't swipe to refresh list.
EDIT:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_jokes, container, false);
mContext = getActivity();
mView = (CoordinatorLayout) view.findViewById(R.id.coordinatorLayout);
TextView tvEmptyText = (TextView) view.findViewById(R.id.tv_empty);
ImageView ivSignal = (ImageView) view.findViewById(R.id.iv_signal);
if (!ConnectionDetector.getInstance(getActivity()).isOnline() && mAdapter == null) {
tvEmptyText.setVisibility(View.VISIBLE);
ivSignal.setVisibility(View.VISIBLE);
showNoInternetSnackbar();
}
// INITIALIZE RECYCLER VIEW
EmptyRecyclerView list = (EmptyRecyclerView) view.findViewById(R.id.list);
mJokes = new ArrayList<>();
mAdapter = new RecyclerJokesAdapter(getActivity(), mJokes, JokesFragment.this, null);
// Progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
showDialog();
View emptyView = inflater.inflate(R.layout.layout_empty_view, container, false);
FloatingActionButton fab1 = (FloatingActionButton) view.findViewById(R.id.fab_funny);
FloatingActionButton fab2 = (FloatingActionButton) view.findViewById(R.id.fab_good_morning);
FloatingActionButton fab3 = (FloatingActionButton) view.findViewById(R.id.fab_good_night);
FloatingActionButton fab4 = (FloatingActionButton) view.findViewById(R.id.fab_all);
menu = (FloatingActionMenu) view.findViewById(R.id.menu_sort_jokes);
fab1.setOnClickListener(this);
fab2.setOnClickListener(this);
fab3.setOnClickListener(this);
fab4.setOnClickListener(this);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeResources(
R.color.refresh_progress_1,
R.color.refresh_progress_2,
R.color.refresh_progress_3);
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
list.setLayoutManager(manager);
list.setEmptyView(emptyView);
list.setItemAnimator(new DefaultItemAnimator());
list.setAdapter(mAdapter);
if (ConnectionDetector.getInstance(mContext).isOnline()) {
loadJokes(1);
} else {
showNoInternetSnackbar();
hideDialog();
}
list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
#Override
public void onLoadMore(final int current_page) {
loadMoreJokes(current_page);
}
});
return view;
}
In onCreate method initialize your adapter, recyclerView and List
List<MyObject> myList = new ArrayList<>();
recyclerViewAdapter = new RecyclerViewAdapter(context, myList)
myRecyclerView.setAdapter(recyclerViewAdapter);
Now, whenever you load data. add the data to your myList and call notifyDataSetChange on your adpater
myList.add(data);
recyclerViewAdapter.notifyDataSetChange();
Use this wrapper class
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import java.util.List;
public abstract class RecyclerWrapperAdapter<E> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
protected Context context;
protected List<E> objects;
public void setContext(Context context) {
this.context = context;
}
public void setObjects(List<E> objects) {
this.objects = objects;
notifyDataSetChanged();
}
public void add(#NonNull E object) {
objects.add(object);
notifyDataSetChanged();
}
public void add(int position, #NonNull E object) {
if (position < objects.size() && position >= 0) {
objects.add(position, object);
notifyItemChanged(position);
notifyDataSetChanged();
} else if (position >= objects.size()) {
objects.add(object);
notifyDataSetChanged();
}
}
public void set(int position, #NonNull E object) {
if (position < objects.size() && position >= 0) {
objects.set(position, object);
notifyItemChanged(position);
} else if (position >= objects.size()) {
objects.add(object);
notifyDataSetChanged();
}
}
public void remove(#NonNull E object) {
objects.remove(object);
notifyDataSetChanged();
}
public void remove(int position) {
if (position >=0 && position < objects.size()) {
objects.remove(position);
notifyDataSetChanged();
}
}
public void removeAll() {
objects.clear();
notifyDataSetChanged();
}
public E getItem(int position) {
return objects.get(position);
}
#Override
public int getItemCount() {
return objects.size();
}
}
Well I have done this way:
MainActivity .java
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener, onRecyclerViewListener {
private RecyclerView mRecyclerView;
private TextView tvEmptyView;
private LinearLayoutManager mLayoutManager;
private List<Object> studentList;
protected Handler handler;
private int count = 0;
private SwipeRefreshLayout swipeRefreshLayout;
private MyRecycleAdapter myRecycleAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swiperefresh);
swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setColorSchemeResources(R.color.blue, R.color.purple, R.color.green, R.color.orange);
tvEmptyView = (TextView) findViewById(R.id.empty_view);
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
studentList = new ArrayList<Object>();
handler = new Handler();
loadData();
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// use a linear layout manager
mRecyclerView.setLayoutManager(mLayoutManager);
myRecycleAdapter = new MyRecycleAdapter(mRecyclerView, studentList, R.layout.list_row, R.layout.progressbar_item, this);
myRecycleAdapter.setLoadMoreEnable(true);
myRecycleAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
count++;
if (count == 4) {
count = 0;
myRecycleAdapter.setLoadMoreEnable(false);
} else {
myRecycleAdapter.setLoadMoreEnable(true);
}
//add null , so the adapter will check view_type and show progress bar at bottom
studentList.add(null);
myRecycleAdapter.notifyItemInserted(studentList.size() - 1);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// remove progress item
studentList.remove(studentList.size() - 1);
myRecycleAdapter.notifyItemRemoved(studentList.size());
//add items one by one
int start = studentList.size();
int end = start + 20;
for (int i = start + 1; i <= end; i++) {
studentList.add(new Student("Student " + i, "AndroidStudent" + i + "#gmail.com"));
myRecycleAdapter.notifyItemInserted(studentList.size());
}
myRecycleAdapter.setLoaded();
//or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
}
}, 1000);
}
});
ItemViewHolderNew.setRecyclerListener(this);
mRecyclerView.setAdapter(myRecycleAdapter);
if (studentList.isEmpty()) {
mRecyclerView.setVisibility(View.GONE);
tvEmptyView.setVisibility(View.VISIBLE);
} else {
mRecyclerView.setVisibility(View.VISIBLE);
tvEmptyView.setVisibility(View.GONE);
}
}
private void loadData() {
for (int i = 1; i <= 20; i++) {
studentList.add(new Student("Student " + i, "androidstudent" + i + "#gmail.com"));
}
}
#Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
}
},5000);
}
#Override
public void onBindView(View view, final ItemViewHolderNew itemViewHolder) {
itemViewHolder.tvName = (TextView) view.findViewById(R.id.tvName);
itemViewHolder.tvEmailId = (TextView) view.findViewById(R.id.tvEmailId);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, Object object, ItemViewHolderNew itemViewHolder) {
Student studentObj = (Student)object;
itemViewHolder.tvName.setText(studentObj.getName());
itemViewHolder.tvEmailId.setText(studentObj.getEmailId());
itemViewHolder.student= studentObj;
}
#Override
public void setClickListener(View view, ItemViewHolderNew itemViewHolder) {
Toast.makeText(view.getContext(), "OnClick :" + itemViewHolder.student.getName() + " \n " + itemViewHolder.student.getEmailId(), Toast.LENGTH_SHORT).show();
}
public static class ItemViewHolderNew extends RecyclerView.ViewHolder{
public TextView tvName, tvEmailId;
public Student student;
private static onRecyclerViewListener mListener;
public static void setRecyclerListener(onRecyclerViewListener listener){
mListener = listener;
}
public ItemViewHolderNew(View itemView) {
super(itemView);
mListener.onBindView(itemView, this);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setClick(v);
}
});
}
private void setClick(View v) {
mListener.setClickListener(v, this);
}
}
}
Add OnLoadMoreListener.java interface
public interface OnLoadMoreListener {
void onLoadMore();
}
Add Student.java as Model class
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String emailId;
public Student(String name, String emailId) {
this.name = name;
this.emailId = emailId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/activity_main">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="No Records Here !"
android:visibility="gone" />
</RelativeLayout>
list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
android:padding="5dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="#+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:id="#+id/tvEmailId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvName"
android:layout_margin="5dp"
android:text="Email Id"
android:textColor="#android:color/black"
android:textSize="12sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvName"
android:layout_margin="5dp"
android:text="Email Id"
android:textColor="#android:color/black"
android:textSize="12sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
progressbar_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:layout_width="match_parent" android:layout_height="match_parent">
<ProgressBar
android:id="#+id/progressBar1"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content" />
</LinearLayout>
Working fine with Endless, swipe to refresh, load more RecyclerView.
Hope this would help you.
Volley RequestQueue uses a thread pool for network requests.
/** Number of network request dispatcher threads to start. */
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4;
Obviously, when you do fast scrolling through the list multiple requests are generated in quick succession.
There is a possibility that the responses are received asynchronously / out of sequence. Also, its possible that the "No more data" responses / error responses etc arrive before the responses with next page of data, which may lead to unexpected behaviour by your app.
Specially watch out for how this would effect your mJokes ArrayList member variable.