Reputation: 105
In my app, I am trying to add sorting such as: sort by popular, top rated, etc. with sorting options in AlertDialog.
My problem is that choosing the option to sort by GridView
doesn't update or change ImageView
I tried the following but it doesn't work:
adapter.notifyDataSetChanged(); gridView.invalidateViews();
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Point;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.BoolRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
/**
* Created by macbook on 9/18/17.
*/
public class MoviesFragment extends Fragment implements AdapterView.OnItemClickListener {
static GridView gridView;
static int width;
static ArrayList<String> posters;
private final static String API_KEY = "0000000000000000000";
final static String URL_BASE = "https://api.themoviedb.org/3/movie/";
static String url_sorted ="popular?api_key=" ;
ImageAdapter adapter;
public MoviesFragment()
{
}
// inflate view and init grideView with set adapter
@Nullable
@Override
public View onCreateView (LayoutInflater inflater, @Nullable ViewGroup
container, @Nullable Bundle savedInstanceState){
View view = inflater.inflate(R.layout.movies_fragment, container, false);
setHasOptionsMenu(true);
// getwidth
WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
if(MainActivity.TABLET)
{
width = size.x/6;
}else
{
width = size.x/2;
}
if(getActivity() != null)
{
posters = new ArrayList<String>();
adapter = new ImageAdapter(getActivity(),posters,width);
gridView = (GridView)view.findViewById(R.id.grideView);
gridView.setAdapter(adapter);
gridView.setColumnWidth(width);
gridView.setOnItemClickListener(this);
}
return view;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getActivity(),position+"",Toast.LENGTH_SHORT).show();
}
@Override
public void onStart() {
super.onStart();
getActivity().setTitle("Most Popular Movies");
loadPoster(url_sorted);
}
public void loadPoster(String url) {
if (isNetworkAvailable()) {
gridView.setVisibility(View.VISIBLE);
getJsonImageUrl(url);
} else {
gridView.setVisibility(View.GONE);
TextView text = new TextView(getActivity());
RelativeLayout relativeLayout = (RelativeLayout) getActivity().findViewById(R.id.relative);
text.setText("no Internet Connection...");
relativeLayout.addView(text);
}
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
public Boolean getJsonImageUrl( String urlSort)
{
Toast.makeText(getActivity(),urlSort,Toast.LENGTH_LONG).show();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, URL_BASE + urlSort+ API_KEY, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
int count = 0 ;
JSONArray obj = null;
try {
obj = response.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
}
while(count <obj.length())
{
JSONObject jsonObject = null;
String imgURL = null;
try {
jsonObject = obj.getJSONObject(count);
imgURL = jsonObject.getString("poster_path");
} catch (JSONException e) {
e.printStackTrace();
}
posters.add(imgURL);
count++;
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(),"ERROR",Toast.LENGTH_LONG).show();
}
}
);
Mysingleton.getInstence(getContext()).addToRequestque(jsonObjectRequest);
return true;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.preferncesMenu:
break;
case R.id.filter:
// Intent i = new Intent(getActivity().getApplication(),SettingAactivity.class);
//startActivity(i);
showSortDialog();
break;
}
return false;
}
private void showSortDialog() {
final CharSequence[] sortBy = new String[] {"Popular", "Top Rated","Latest","Upcoming","Now playing"};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Sort by");
builder.setSingleChoiceItems(sortBy, -1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String newUrl;
gridView.setAdapter(null);
switch(which)
{
case 0:
newUrl = "popular?api_key=";
getActivity().setTitle("Most Popular Movies");
//loadPoster(newUrl);
break;
case 1:
newUrl = "top_rated?api_key=";
getActivity().setTitle("Top Rated Movies");
adapter.notifyDataSetChanged();
gridView.invalidateViews();
loadPoster(newUrl);
Toast.makeText(getActivity(),newUrl,Toast.LENGTH_LONG).show();
dialog.dismiss();
break;
case 2:
url_sorted = "latest?api_key=";
getActivity().setTitle("latest Movies");
break;
case 3:
url_sorted = "upcoming?api_key=";
getActivity().setTitle("UpComing Movies");
break;
case 5:
url_sorted = "now_playing?api_key=";
getActivity().setTitle("Now Playing Movies");
break;
}
}
});
builder.create().show();
}
}
Upvotes: 2
Views: 3553
Reputation: 5392
I only see you calling notifyDataSetChanged after you set the adapter to null. I'm not sure why you would set the adapter to null and then attempt to use it. You should be crashing, not just seeing data not updated.
After your getjson call you should be calling notifyDataSetChanged to show all the new items you got. If sort is to change the sort order, then you should implement your sort on the list, then call notifyDataSetChanged again.
I'm not sure why you are nulling it out. If you do this, you should be fine.
Upvotes: 0
Reputation: 105
The problem was calling notifyDataSetChanged() from a non UI Thread.
So after call notifyDataSetChanged() from UI Thread its work perfectly
Code:
public void refresh()
{
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
gridView.invalidate();
}
});
}
Upvotes: 3
Reputation: 766
Basically inside your adapter you need to have mechanism to pass in/update the data object.
Add a method inside your adapter class which will be called when new data is available.
public void swapItems(List<Item> itemsList){
mItemsList.clear();
mItemsList.addAll(itemsList);
notifyDataSetChanged();
}
Then from your activity, after you have received your new data, just call this method from your adapter instance.
adapter.swapItems(newItemsList);
Just change the above code to match your data type. But that's basically how it's done. And if you want to be more fancy explore Android data binding.
Upvotes: 1