GridView not refreshing after changing setting - android

I am building this movie app that displays movies in a gridview on the main panel, then I can click them and display some information about that movie, also I have some settings to change the criteria of the movies displayed: popular, top rated or favorites. The favorites are a local collection saved in sharedPreferences chosen by the user.
Here is where it all happens:
public class MovieFragment extends Fragment{
public String[][] matrixMoviesInfo;
public GridView gridView;
public String[] mArrayImages;
private String baseUrl;
private String apiKey;
public MovieFragment(){
matrixMoviesInfo = new String[20][10];
mArrayImages = new String[20];
baseUrl = "http://api.themoviedb.org/3/movie/";
apiKey = "?api_key=37068e0a72b2cc1751b4246899923ba7";
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
gridView = (GridView) rootView.findViewById(R.id.gridview);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Intent intent = new Intent(getActivity(), DetailActivity.class)
.putExtra(Intent.EXTRA_TEXT, matrixMoviesInfo[position]);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
return rootView;
}
private void setImages() {
for(int i=0;i<mArrayImages.length;i++){
if(matrixMoviesInfo[i][0]!=null) {
mArrayImages[i] = matrixMoviesInfo[i][0];
}
}
gridView.setAdapter(null);
gridView.setAdapter(new ImageAdapter(getActivity(), mArrayImages));
Log.v(null, "SETIMAGESCALLED");
}
private void updateMovies() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String preference = prefs.getString(getString(R.string.pref_sortby_key), getString(R.string.pref_sortby_default));
if(preference.toLowerCase().equals("favorites")){
SharedPreferences preferences = getContext().getSharedPreferences("favorites_list", Context.MODE_PRIVATE);
Map<String, ?> allEntries = preferences.getAll();
String[] keyNames = new String[allEntries.size()];
Log.v(null,"SIZE: "+allEntries.size());
String[] keyValues;
int iterator=0;
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
Log.v("KEY: " +entry.getKey(), "VALUE: "+entry.getValue().toString());
}
for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
if(entry.getKey()!=null) {
keyNames[iterator] = entry.getKey();
keyValues = entry.getValue().toString().split("#");
for (int i = 0; i < 10; i++) {
Log.v("INDEX: " + i, " VALUES: " + keyValues[i]);
matrixMoviesInfo[iterator][i] = keyValues[i];
}
iterator++;
}
}
setImages();
}else{
Log.v(null,"EXECUTETASK");
new FetchMoviesTask().execute(baseUrl+preference.toLowerCase()+apiKey, "i");
}
}
#Override
public void onStart() {
super.onStart();
updateMovies();
}
public class FetchMoviesTask extends AsyncTask<String, String, Void> {
private final String LOG_TAG = FetchMoviesTask.class.getSimpleName();
private Void getMovieDetailsFromJson(String movieJSONstr) throws JSONException {
final String OWM_RESULTS = "results";
final String OWM_ID = "id";
final String OWM_POSTERPATH = "poster_path";
final String OWM_TITLE = "original_title";
final String OWM_OVERVIEW = "overview";
final String OWM_USERRATING = "vote_average";
final String OWM_RELEASEDATE = "release_date";
JSONObject movieJson = new JSONObject(movieJSONstr);
JSONArray movieArray = movieJson.getJSONArray(OWM_RESULTS);
for(int i = 0; i < movieArray.length(); i++) {
JSONObject movieObj = movieArray.getJSONObject(i);
matrixMoviesInfo[i][0] = movieObj.getString(OWM_POSTERPATH);
matrixMoviesInfo[i][1] = movieObj.getString(OWM_ID);
matrixMoviesInfo[i][2] = movieObj.getString(OWM_TITLE);
matrixMoviesInfo[i][3] = movieObj.getString(OWM_OVERVIEW);
matrixMoviesInfo[i][4] = movieObj.getString(OWM_USERRATING);
matrixMoviesInfo[i][5] = movieObj.getString(OWM_RELEASEDATE);
}
for(int i=0;i<20;i++) {
new FetchMoviesTask().execute(baseUrl + matrixMoviesInfo[i][1] + "/reviews" + apiKey, Integer.toString(i));
new FetchMoviesTask().execute(baseUrl + matrixMoviesInfo[i][1] + "/videos" + apiKey, "v");
}
Log.v(null,"GETMOVIEDETAILS");
return null;
}
private Void getMovieReviewsFromJson(String movieJSONstr, String position) throws JSONException{
int pos = Integer.parseInt(position);
final String OWM_RESULTS = "results";
final String OWM_AUTHOR = "author";
final String OWM_CONTENT = "content";
final String OWM_TOTALRESULTS = "total_results";
JSONObject movieJson = new JSONObject(movieJSONstr);
JSONArray movieArray = movieJson.getJSONArray(OWM_RESULTS);
int numberOfResults = Integer.parseInt(movieJson.getString(OWM_TOTALRESULTS));
if(numberOfResults >= 1) {
matrixMoviesInfo[pos][6] = movieArray.getJSONObject(0).getString(OWM_AUTHOR);
matrixMoviesInfo[pos][7] = movieArray.getJSONObject(0).getString(OWM_CONTENT);
}
if(numberOfResults > 1) {
matrixMoviesInfo[pos][8] = movieArray.getJSONObject(1).getString(OWM_AUTHOR);
matrixMoviesInfo[pos][9] = movieArray.getJSONObject(1).getString(OWM_CONTENT);
}
return null;
}
private Void getMovieVideosFromJson(String movieJSONstr){
return null;
}
#Override
protected Void doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String movieJSONstr = null;
try{
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if(inputStream == null){
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while((line = reader.readLine()) != null){
buffer.append(line + "\n");
}
if(buffer.length() == 0){
movieJSONstr = null;
}
movieJSONstr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
return null;
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("MovieFragment", "Error closing stream", e);
}
}
}
try{
if(params[1].equals("i")){
Log.v(null,"EXECUTEGETMOVIEDETAILS");
return getMovieDetailsFromJson(movieJSONstr);
}
else {
if (params[1].equals("v")){
return getMovieVideosFromJson(movieJSONstr);}
else{
return getMovieReviewsFromJson(movieJSONstr, params[1]);}
}
}catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
String[] mArrayImages = new String[20];
for(int i=0;i<20;i++){
mArrayImages[i] = matrixMoviesInfo[i][0];
}
gridView.setAdapter(new ImageAdapter(getActivity(), mArrayImages));
Log.v(null, "IMAGES SET GRIDVIEW REFRESHED");
}
}
Class Explanation:
There is 2 paths:
Popular or TopRated: starts on method UpdateMovies, then executes the asynctask to fetch data from the api, followed by the execution of the getMoviesFromJson that extracts all the information related to all movies. Then it ends on onPostExecute that populates the gridview with the ImageAdapter.
Favorites: starts on method UpdateMovies, here it fetchs the data from sharedpreferences and populates the array with that data, then it calls the method setImages to populate the gridView with the ImageAdapter.
Here is my problem: when I am displaying the popular movies and change the setting to favorites, it displays the right movies on the sharedpreferences but it is not "cleaning" the remaining ones from the gridview.
Also how can I adjust the scroll of the gridview to match the cells it has (when there is no movie to populate a cell, I hide it like this:
imageView.setVisibility(View.GONE);

Make an Adapter for the gridview that extends from BaseAdapter, or use an Adapter that extends from BaseAdapter.
then call notifyDataSetChanged on that adapter when the contents of your collection has changed.

Related

How to pass custom object with checked checkbox through intent in adapter to activity

I am displaying hotels in listview with checkbox,image and text. when user click on checkbox then put that checked hotel_id into bundle. And pass to it's super class.
When i am selected hotels and click on button on main activity my logcat shows NullPointerException. I will check my code with debugger. I can find getting Bundle=null. So please help to find the hotel_id when click's on checkbox and send that all selected hotel_id to its main Activity.
Here is my ListViewAdapter class.
public class ListViewAdapter extends BaseAdapter {
Context context;
LayoutInflater inflater;
ArrayList<Product> AllMenu = new ArrayList<>();
ImageLoader imageLoader;
int checkCounter = 0;
public ListViewAdapter(Context context, ArrayList<Product> itemlist) {
this.context = context;
AllMenu = itemlist;
imageLoader = new ImageLoader(context);
checkCounter = 0;
}
public int getCount() {
return AllMenu.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return 0;
}
public View getView(final int position, final View convertView, final ViewGroup parent) {
// Declare Variables
final Product tempMenu = AllMenu.get(position);
final CheckBox c;
final ImageView image_path;
final TextView name, location, desc;
final Bundle b = new Bundle();
final Intent intent = new Intent(context.getApplicationContext(),Hotels.class);
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View view = inflater.inflate(R.layout.viewpage, parent, false);
// Get the position
c = (CheckBox) view.findViewById(R.id.mycheckbox);
name = (TextView) view.findViewById(R.id.fh_name);
location = (TextView) view.findViewById(R.id.fh_loc);
desc = (TextView) view.findViewById(R.id.fh_desc);
image_path = (ImageView) view.findViewById(R.id.image_all_main);
c.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (c.isChecked() && checkCounter >= 3) {
AllMenu.get(position).setSelected(false);
c.setChecked(false);
Toast.makeText(context, "You can select max 3 hotels!!", Toast.LENGTH_SHORT).show();
} else {
Product p = (AllMenu).get(position);
p.setSelected(c.isChecked());
if (c.isChecked()) {
checkCounter++;
} else {
checkCounter--;
}
}
StringBuffer responseText = new StringBuffer();
responseText.append("The following were selected...");
ArrayList<Product> p = AllMenu;
for (int i = 0; i < p.size(); i++) {
Product pp = p.get(i);
if (pp.isSelected()) {
//here is i want hotel id when i am cliked on hotel.
//and save it into bundle and i am get bundle into it's super class
String[] h = new String[0];
b.putStringArray(String.valueOf(pp.getId()),hid);
intent.putExtras(b);
//Here is how i can pass custom object to string
responseText.append("\n" + pp.getName() + "\t");
responseText.append("\t" + pp.getLocation());
}
}
Toast.makeText(context, responseText, Toast.LENGTH_SHORT).show();
}
});
c.setTag(tempMenu);
c.setChecked(tempMenu.isSelected());
name.setText(tempMenu.getName());
location.setText(tempMenu.getLocation());
desc.setText(tempMenu.getDescription().trim());
imageLoader.DisplayImage(tempMenu.getImage_path(), image_path);
return view;
}
}
And i will get that bundle into this Hotels.class
Here is my Hotels.class
public class Hotels extends Activity
{
// Declare Variables
JSONArray jsonarray = null;
private static final String TAG_ID= "id";
public static final String TAG_NAME = "name";
public static final String TAG_LOCATION = "location";
public static final String TAG_DESC = "description";
String f_date,l_date;
int[] hotel_id = new int[0];
ProgressDialog loading;
ListView list;
Button booknow;
ListViewAdapter adapter;
private ArrayList<Product> itemlist;
Product product;
static String Array = "MyHotels";
View view;
CheckBox click;
String hotel = "http://app.goholidays.info/getHotelData.php";
String booking = "http://app.goholidays.info/insertIntoBooking.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_item_layout);
product = new Product();
itemlist = new ArrayList<Product>();
new ReadJSON().execute();
click = (CheckBox) findViewById(R.id.mycheckbox);
booknow = (Button) findViewById(R.id.bookhotel);
product = new Product();
list = (ListView) findViewById(R.id.myimagelist);
Calendar c = Calendar.getInstance();
System.out.println("Current time => "+c.getTime());
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(Hotels.this);
SharedPreferences.Editor editor = sp.edit();
final String user_id = sp.getString("id", TAG_ID);
final String start_date = sp.getString("start_date", f_date);
final String end_date = sp.getString("end_date", l_date );
final String chk_status = df.format(c.getTime());
booknow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//here i want get all selected hotel_id into bundle.
//And i want pass that hotel_id to my database.
Bundle bundle = getIntent().getExtras();
String[] hotel_id = bundle.getStringArray(String.valueOf(product.getId()));
Submit(start_date,end_date,hotel_id,chk_status,user_id);
}
});
}
class ReadJSON extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(Hotels.this,"Fetching Data","Please wait...",false,false);
}
#Override
protected String doInBackground(String... args) {
Product tempMenu;
try {
JSONObject jsonobject = JSONfunctions.getJSONfromURL(hotel);
jsonarray = jsonobject.optJSONArray(Array);
//parse date for dateList
for (int i = 0; i < jsonarray.length(); i++) {
tempMenu = new Product();
jsonobject = jsonarray.getJSONObject(i);
tempMenu.setId(jsonobject.getInt("hotel_id"));
tempMenu.setName(jsonobject.getString("name"));
tempMenu.setLocation(jsonobject.getString("location"));
tempMenu.setImage_path(jsonobject.getString("image_name"));
tempMenu.setDescription(jsonobject.getString("description"));
tempMenu.setFacility1(jsonobject.getString("facility1"));
tempMenu.setFacility2(jsonobject.getString("facility2"));
tempMenu.setFacility3(jsonobject.getString("facility3"));
tempMenu.setFacility4(jsonobject.getString("facility4"));
tempMenu.setStar(jsonobject.getString("star"));
itemlist.add(tempMenu);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
adapter = new ListViewAdapter(Hotels.this, itemlist);
list.setAdapter(adapter);
loading.dismiss();
}
}
private void Submit(final String start_date, final String end_date, final String[] hotel_id, final String chk_status, final String user_id) {
class BackTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String start_dtae = params[0];
String end_date = params[1];
String hotel_id = params[2];
String user_id = params[3];
String chk_status = params[4];
try {
URL url = new URL(booking);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream os = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
String data = URLEncoder.encode("start_date", "UTF-8") +"="+URLEncoder.encode(start_dtae, "UTF-8") + "&" +
URLEncoder.encode("end_date", "UTF-8") +"="+URLEncoder.encode(end_date, "UTF-8") + "&" +
URLEncoder.encode("hotel_id", "UTF-8") +"="+URLEncoder.encode(hotel_id, "UTF-8") + "&" +
URLEncoder.encode("user_id", "UTF-8") +"="+URLEncoder.encode(user_id, "UTF-8") + "&" +
URLEncoder.encode("chk_status", "UTF-8") +"="+URLEncoder.encode(chk_status, "UTF-8");
bufferedWriter.write(data);
bufferedWriter.flush();
bufferedWriter.close();
os.close();
InputStream is = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 8);
String responce = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
responce += line;
}
bufferedReader.close();
is.close();
httpURLConnection.disconnect();
return responce;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(),"Book Success"+result,Toast.LENGTH_SHORT).show();
}
}
BackTask lg=new BackTask();
lg.execute(start_date, end_date, chk_status, String.valueOf(hotel_id), user_id);
}
}
My custom object class is here.
public class Product extends HashMap<String, String> {
private String name;
private int hotel_id;
private String description;
private String location;
private String image_path;
boolean selected;
public boolean isSelected(){
return selected;
}
public void setSelected(boolean selected){
this.selected = selected;
}
public void setId (int hotel_id) { this.hotel_id = hotel_id;}
public int getId() {
return hotel_id;
}
public void setName (String name) { this.name = name;}
public String getName() {
return name;
}
public void setLocation(String location) {
this.location = location;
}
public String getLocation() {
return location;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setImage_path(String image_path) {
this.image_path = image_path;
}
public String getImage_path() {
return image_path;
}
}
The problem is you are only putting data to intent. It is just worth if You put bundle or data inside intent object with using startActivity.
If you want to get selected Hotel id's just make a public array like:-
public class Hotels extends Activity
{
public ArrayList<Integer> hotel_ids=new ArrayList<>();
}
and inside adapter while selecting check box put id in arrayList with the use of context as below and if unchecked remove hotel_id from that array list :-
c.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (c.isChecked() && checkCounter >= 3) {
AllMenu.get(position).setSelected(false);
c.setChecked(false);
Toast.makeText(context, "You can select max 3 hotels!!", Toast.LENGTH_SHORT).show();
} else {
Product p = (AllMenu).get(position);
p.setSelected(c.isChecked());
if (c.isChecked()) {
if(context instanceof Hotels){
((Hotels)context).hotel_ids.add(p.getId());
}
checkCounter++;
} else {
if(context instanceof Hotels){
((Hotels)context).hotel_ids.remove(p.getId());
}
checkCounter--;
}
}
}
}
It may help you out. With the above one you will always find selected Hotel_ids.
you can do something like this.
1> in getview method you can do checked listener like below
viewHolder.chkbox.setOnCheckedChangeListener(new CheckUpdateListener(itemList.get(position));
2> make new class for CheckUpdatelistener with argument constructor of model class
private final class CheckUpdateListener implements CompoundButton.OnCheckedChangeListener {
private final Product product;
private CheckUpdateListener(Product product) {
this.product = product;
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.i("onCheckedChanged", "isChecked: " + isChecked);
product.setChecked(isChecked);
notifyDataSetChanged();
}
}
3> in main activity on button click listener you can do code like this
Arraylist<Product> selectedProduct = new ArrayList<>();
if (itemList.size() > 0) {
for (int i = 0; i < itemList.size(); i++) {
if (itemList.get(i).isChecked()) {
try {
selectedProduct.add(itemList.get(i));
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}

ArrayAdapter is null even after getting a string array as a parameter

I'm working on the Sunshine app in the Developing Android App course by Udacity. Currently stuck in lesson 2. I've listed down the MainActivity.java that contains a listview that is populated by a network call in the AsyncTask as an inner class in the MainActivity.java. But the application crashes, due to a null pointer exception, as the array adapter is null. I've tried debugging, and the weekForecast (i.e., the ArrayList that stores the parsed data, and is a parameter to the creation of the ArrayAdapter) does have valid parsed data. Thanks for the help in advance.
public class MainActivity extends AppCompatActivity {
ListView listView;
ArrayAdapter<String> arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.listview_forecast);
GettingWeatherFromNetwork gettingWeatherFromNetwork = new GettingWeatherFromNetwork();
gettingWeatherFromNetwork.execute("94043");
listView.setAdapter(arrayAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case R.id.action_settings : return true;
case R.id.action_refresh : GettingWeatherFromNetwork gettingWeatherFromNetwork = new GettingWeatherFromNetwork();
gettingWeatherFromNetwork.execute("94043");
return true;
}
return super.onOptionsItemSelected(item);
}
public class GettingWeatherFromNetwork extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = GettingWeatherFromNetwork.class.getSimpleName();
//Removed API KEY. But it is a part of the main code I'm running.
private final String API_KEY = " ";
#Override
protected String[] doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String forecastJsonStr = null;
String format = "json";
String units = "metric";
int noOfDays = 7;
try {
final String BASE_URL = "http://api.openweathermap.org/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
final String MODE_PARAM = "mode";
final String UNITS_PARAM = "units";
final String COUNT_PARAM = "cnt";
final String KEY_PARAM = "appid";
Uri builtURI = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM,params[0])
.appendQueryParameter(MODE_PARAM,format)
.appendQueryParameter(UNITS_PARAM,units)
.appendQueryParameter(COUNT_PARAM, String.valueOf(noOfDays))
.appendQueryParameter(KEY_PARAM,API_KEY)
.build();
String Url = builtURI.toString();
URL url = new URL(Url);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}
forecastJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, String.valueOf(e));
return null;
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, String.valueOf(e));
}
}
}
String [] weatherForecast = new String[0];
WeatherParser weatherParser = new WeatherParser();
try {
weatherForecast = weatherParser.getWeatherDataFromJson(forecastJsonStr,7);
} catch (JSONException e) {
e.printStackTrace();
}
return weatherForecast;
}
#Override
protected void onPostExecute(String[] s) {
List<String> weekForecast = new ArrayList<String>(Arrays.asList(s));
arrayAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.list_item_forecast,R.id.list_item_forecast_textview,weekForecast);
}
}
}
Try removing the line
listView.setAdapter(arrayAdapter);
from onCreate method and add it in onPostExecute() method of AsyncTask, after initialising the arrayAdapter.
#Override
protected void onPostExecute(String[] s) {
List<String> weekForecast = new ArrayList<String>(Arrays.asList(s));
arrayAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.list_item_forecast,R.id.list_item_forecast_textview,weekForecast);
//set adapter set to listview after initialzing it.
listView.setAdapter(arrayAdapter);
}

Starting Activity From Fragment

I have two AsyncTasks (FetchDataFromApi , FetchDataFromDb) ,they both have an implementation for "onPostExecute" method each one of them starts DetailActivity by calling the passDataToDetailedActivity method .
whenever i start the DetailedActivity from the FetchFromApi onPostExecute method it works well ,
but the Whole problem is when i try to start the DetailedActivity from FetchFromDb onPostExecute method cuz some components of the DetailedActivity UI just doesn't appear and others do .
Please Help ,, thanks in advance :)
public class MainFragment extends Fragment {
public final static String API_KEY = "b932ba435fc93a5944938fe9d44cd198";
public final String BASE_URL = "http://api.themoviedb.org/3/discover/movie?sort_by=&api_key=";
ArrayList<Movie> movies = new ArrayList<>();
movieAdapter adapter;
GridView gridview;
DbOpenHelper dbOpenHelper;
ArrayList<Movie> FavList = new ArrayList<>();
public MainFragment() {
}
public MainFragment(String SortBy) {
if (SortBy == "fav") {
new FetchDataFromDb().execute();
} else {
new FetchDataFromApi(SortBy).execute();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
gridview = (GridView) getActivity().findViewById(R.id.gridView);
adapter = new movieAdapter(getActivity(), R.layout.movie_item, movies);
return view;
}
class FetchDataFromApi extends AsyncTask<String, Void, Boolean> {
String SORT_CATEGORY;
FetchDataFromApi(String paramUrl) {
SORT_CATEGORY = paramUrl;
}
#Override
protected Boolean doInBackground(String... params) {
HttpURLConnection urlConnection = null;
try {
Uri uriBuilder = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter("sort_by", SORT_CATEGORY)
.appendQueryParameter("api_key", API_KEY)
.build();
URL url = new URL(uriBuilder.toString());
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
String response = sb.toString();
ParseJsonData(response);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
return null;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
gridview.setAdapter(adapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
PassDataToDetailedActivity(position);
}
});
}
private void ParseJsonData(String response) throws JSONException {
String PosterBaseUrl = "http://image.tmdb.org/t/p/";
String LargePoster = "w185";
String SmallPoster = "";
final String RESULTS = "results";
final String ORIGINAL_TITLE = "original_title";
final String OVERVIEW = "overview";
final String RELEASE_DATE = "release_date";
final String POSTER_PATH = "poster_path";
final String VOTE_AVERAGE = "vote_average";
final String POPULARITY = "popularity";
final String ID = "id";
JSONObject jsono = new JSONObject(response);
Log.v("Json", response);
JSONArray jarray = jsono.getJSONArray(RESULTS);
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
String id = object.getString(ID);
String title = object.getString(ORIGINAL_TITLE);
String releaseDate = object.getString(RELEASE_DATE);
String overView = object.getString(OVERVIEW);
String voteAverage = object.getString(VOTE_AVERAGE);
String popularity = object.getString(POPULARITY);
String posterPath = object.getString(POSTER_PATH);
String BigPoster = PosterBaseUrl + LargePoster + posterPath;
String MinPoster = PosterBaseUrl + SmallPoster + posterPath;
Movie m = new Movie();
m.setId(id);
m.setTitle(title);
m.setReleaseDate(releaseDate);
m.setOverView(overView);
m.setVoteAverage(voteAverage);
m.setPopularity(popularity);
m.setLargePoster(BigPoster);
m.setMinPoster(MinPoster);
movies.add(m);
}
}
}
private void PassDataToDetailedActivity(int position) {
String id = movies.get(position).getId();
String title = movies.get(position).getTitle();
String releaseDate = movies.get(position).getReleaseDate();
String overView = movies.get(position).getOverView();
String voteAverage = movies.get(position).getVoteAverage();
String popularity = movies.get(position).getPopularity();
String BigPoster = movies.get(position).getLargePoster();
String MinPoster = movies.get(position).getMinPoster();
Intent intent = new Intent(MainActivity.context, DetailedActivity.class);
intent.putExtra("id", id);
intent.putExtra("title", title);
intent.putExtra("releaseDate", releaseDate);
intent.putExtra("overView", overView);
intent.putExtra("voteAverage", voteAverage);
intent.putExtra("popularity", popularity);
intent.putExtra("MaxPoster", BigPoster);
intent.putExtra("MinPoster", MinPoster);
startActivity(intent);
}
public class FetchDataFromDb extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
dbOpenHelper = new DbOpenHelper(MainActivity.context);
movies.clear();
movies = dbOpenHelper.getAllFavoritePosters();
Log.v("database count", Integer.toString(FavList.size()));
return null;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
Log.v("database status", "Finished From Db");
adapter.notifyDataSetChanged();
gridview.setAdapter(adapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
PassDataToDetailedActivity(position);
}
});
}
}
}
Try this code:
Intent in = new Intent(getActivity(), Opening_Activtiy_Name().class);
getActivity().startActivity(in);
Note: Bring your gridListener out of that post execute method

Imageview not showing unless rotate or resume

I am working on my movie project which fetch movie poster from URL, and then putting them into a gridview. I use asynctask to fetch JSON and the parse the url within the json file. However, when I launch my app, the grid is all empty and doing nothing until I rotate my screen or resume my app. Once I rotate my screen or resume my app. It shows all picture. I remove my api key on my code here.
public class FetchMovieTask extends AsyncTask<Void, Void, ArrayList<String>> {
private final String LOG_TAG = FetchMovieTask.class.getSimpleName();
#Override
protected ArrayList<String> doInBackground(Void... params) {
String api_key = "";
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String movieJsonStr = null;
try {
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.authority("api.themoviedb.org")
.appendPath("3")
.appendPath("discover")
.appendPath("movie")
.appendQueryParameter("api_key", api_key);
String myUrl = builder.build().toString();
URL Url = new URL(myUrl);
Log.v(LOG_TAG, myUrl);
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) Url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
movieJsonStr = null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
movieJsonStr = null;
}
movieJsonStr = buffer.toString();
Log.v("KPN", movieJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attempting
// to parse it.
movieJsonStr = null;
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
MovieURL = getPosterUrlFromJson(movieJsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
}
private ArrayList<String> getPosterUrlFromJson(String forcastMovieStr)
throws JSONException {
final String OWM_PosterUrl = "poster_path";
final String OWM_releaseDate = "release_date";
final String OWM_overview = "overview";
final String OWM_vote_average = "vote_average";
final String OWM_original_title = "original_title";
final String OWM_results = "results";
JSONObject movieJson = new JSONObject(forcastMovieStr);
JSONArray movieArray = movieJson.getJSONArray(OWM_results);
ArrayList<String> resultStrs = new ArrayList<>();
String posterurl = "http://image.tmdb.org/t/p/w185/";
for (int i = 0; i < movieArray.length(); i++) {
// For now, using the format "Day, description, hi/low"
String title;
String overview;
String poster;
// Get the JSON object for movie poster
JSONObject moveposter = movieArray.getJSONObject(i);
poster = moveposter.getString(OWM_PosterUrl);
resultStrs.add(i,posterurl + poster);
}
return resultStrs;
}
protected void onPostExecute(ArrayList<String> strings) {
MovieURL.clear();
for (String s : strings) {
MovieURL.add(s);
}
}
Main:
public class MainActivity extends AppCompatActivity {
public static ArrayList<String> MovieURL = new ArrayList();
public static ImageListAdapter mImageListAdapter;
public GridView gridview;
#Override
protected void onStart() {
super.onStart();
new FetchMovieTask().execute();
mImageListAdapter = new ImageListAdapter(this,MovieURL);
gridview.setAdapter(mImageListAdapter);
gridview.invalidateViews();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
}
private void updateMovieURL(){
new FetchMovieTask().execute();
gridview.invalidateViews();
}
ImagelistAdapter class
public class ImageListAdapter extends ArrayAdapter {
private Context context;
private LayoutInflater inflater;
private ArrayList<String> imageUrls;
public ImageListAdapter(Context context, ArrayList <String> imageUrls) {
super(context, R.layout.image_view, imageUrls);
this.context = context;
this.imageUrls = imageUrls;
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
convertView = inflater.inflate(R.layout.image_view, parent, false);
}
Picasso.with(context).load(imageUrls.get(position))
.placeholder(R.drawable.loading)
.into((ImageView) convertView);
return convertView;
}
}
THanks guys
In postExecute do this:
protected void onPostExecute(ArrayList<String> strings) {
MovieURL.clear();
for (String s : strings) {
MovieURL.add(s);
}
mImageListAdapter.notifyDataSetChanged();
}
I found my problem on the asynctask, I didnt override the onPostExecute method. After I override my onPostExecute, I initial my grid view
#Override
protected void onPostExecute(ArrayList<String> strings) {
super.onPostExecute(strings);
mImageListAdapter = new ImageListAdapter(MainActivity.this, MovieURL);
gridview.setAdapter(mImageListAdapter);
}

Android Loader: Cannot load data to ListView

The problem is that, I don't get any error, except that the data doesn't get loaded in the textViews of the customized ListView, all I get is a blank output. I didn't have problems before I started using Loaders.
MSKFragment.java (The Fragment class)
public class MSKFragment extends android.support.v4.app.Fragment implements LoaderManager.LoaderCallbacks<Cursor>
{
private ServiceAdapter mServiceAdapter;
public static final int SERVICE_LOADER = 0;
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle args)
{
Uri serviceUri = ServiceContract.ServiceEntry.buildServiceUri(i);
return new CursorLoader(getActivity(), serviceUri, null, null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
mServiceAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
mServiceAdapter.swapCursor(null);
}
public MSKFragment()
{
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.menu_fragment_msk, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
if (id == R.id.action_refresh)
{
//Moving functions to a helper class, so that when Activity starts the data can be displayed
updateServices();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
mServiceAdapter = new ServiceAdapter(getActivity(), null, 0);
View rootView = inflater.inflate(R.layout.fragment_msk, container, false);
ListView listView = (ListView) rootView.findViewById(R.id.listViewMainService);
listView.setAdapter(mServiceAdapter);
return rootView;
}
#Override
public void onStart()
{
super.onStart();
//Refresh called and service updated when activity starts
updateServices();
}
private void updateServices()
{
FetchServicesTask serviceTask = new FetchServicesTask(getActivity());
serviceTask.execute();
}
}
ServiceAdapter.java (Custom Adapter class)
public class ServiceAdapter extends CursorAdapter
{
public ServiceAdapter(Context context, Cursor c, int flags)
{
super(context, c, flags);
}
private String convertCursorRowToUXFormat(Cursor cursor) {
// get row indices for our cursor
int idx_name = cursor.getColumnIndex(ServiceContract.ServiceEntry.COLUMN_NAME);
int idx_organizationName = cursor.getColumnIndex(ServiceContract.ServiceEntry.COLUMN_ORGANIZATION_NAME);
int idx_price = cursor.getColumnIndex(ServiceContract.ServiceEntry.COLUMN_PRICE);
return cursor.getString(idx_name) + "-" + cursor.getString(idx_organizationName) +
" - " + cursor.getString(idx_price);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
View view = LayoutInflater.from(context).inflate(R.layout.list_item_main, parent, false);
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor)
{
TextView tv = (TextView)view;
tv.setText(convertCursorRowToUXFormat(cursor));
}
}
FetchServicesTask.java (Performing the Async Task)
public class FetchServicesTask extends AsyncTask<String, Void, Void>
{
private final String LOG_TAG = FetchServicesTask.class.getSimpleName();
private final Context mContext;
private boolean DEBUG = true;
public FetchServicesTask(Context context )
{
mContext = context;
}
private String[] getServicesDatafromJson(String serviceJsonStr) throws JSONException
{
final String MSK_NAME = "name";
final String MSK_PRICE = "price";
final String MSK_ORG_NAME = "organizationName";
final String MSK_POSTED_USER = "postedUser";
final String MSK_PROFILE = "profile";
int totalResults = 25;
String resultStrs[] = new String[totalResults];
try
{
JSONArray serviceArray = new JSONArray(serviceJsonStr);
Vector<ContentValues> cVVector = new Vector<ContentValues>(serviceArray.length());
for(int i=0;i<serviceArray.length();i++)
{
String name, organizationName, price;
JSONObject serviceObject = serviceArray.getJSONObject(i);
name = serviceObject.getString(MSK_NAME);
price = serviceObject.getString(MSK_PRICE);
JSONObject postedUserObject = serviceObject.getJSONObject(MSK_POSTED_USER);
JSONObject profileObject = postedUserObject.getJSONObject(MSK_PROFILE);
organizationName = profileObject.getString(MSK_ORG_NAME);
ContentValues serviceValues = new ContentValues();
serviceValues.put(ServiceContract.ServiceEntry.COLUMN_NAME, name);
serviceValues.put(ServiceContract.ServiceEntry.COLUMN_ORGANIZATION_NAME, organizationName);
serviceValues.put(ServiceContract.ServiceEntry.COLUMN_PRICE, price);
cVVector.add(serviceValues);
}
int inserted = 0;
if(cVVector.size()>0)
{
ContentValues[] cvArray = new ContentValues[cVVector.size()];
cVVector.toArray(cvArray);
inserted = mContext.getContentResolver().bulkInsert(ServiceContract.ServiceEntry.CONTENT_URI, cvArray);
}
Log.d(LOG_TAG, "FetchServicesTask Complete. " + inserted + " Inserted");
}
catch(JSONException e)
{
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
/////////////////////////////// NETWORKING BOILER PLATE ///////////////////////////
#Override
protected Void doInBackground(String... params)
{
if (params.length == 0)
{
return null;
}
HttpURLConnection urlConnection = null; //Streaming data using HTTP
String serviceJsonStr = null; //raw JSON response
BufferedReader reader = null; //read text from character i/p stream
int pageNo = 1;
int numResults = 5;
try
{
//-------------------------CONNECTION--------------------//
final String SERVICE_BASE_URL = "http://myservicekart.com/public/";
final String SEARCH_BASE_URL = "http://myservicekart.com/public/search?";
final String SEARCH_PARAM = "search";
final String PAGE_PARAM = "pageno";
/*Using a helper class UriBuilder for building and manipulating URI references*/
Uri builtServiceUri = Uri.parse(SERVICE_BASE_URL);
Uri builtSearchUri = Uri.parse(SEARCH_BASE_URL).buildUpon().
appendQueryParameter(SEARCH_PARAM, "").
appendQueryParameter(PAGE_PARAM, Integer.toString(pageNo)).
build();
URL searchUrl = new URL(builtSearchUri.toString());
Log.v(LOG_TAG, "Built SearchUri" +builtSearchUri.toString());
urlConnection = (HttpURLConnection) searchUrl.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
//------------------------BUFFERING---------------------//
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if(inputStream==null)
{
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line = reader.readLine()) != null)
{
buffer.append(line + "\n");
}
if(buffer.length()==0)
{
return null;
}
serviceJsonStr = buffer.toString();
getServicesDatafromJson(serviceJsonStr);
Log.v(LOG_TAG, "Services JSON String: " +serviceJsonStr);
}
catch(IOException e)
{
Log.e(LOG_TAG, "Error cannot connect to URL", e);
return null;
}
catch (JSONException e)
{
e.printStackTrace();
}
finally
{
if(urlConnection!=null)
{
urlConnection.disconnect();
}
if(reader!=null)
{
try
{
reader.close();
}
catch (final IOException e)
{
Log.e(LOG_TAG,"Error closing stream",e);
}
}
}
return null;
}
}
In onCreate, you need to init your loader:
getLoaderManager().initLoader(SERVICE_LOADER , null, this);
// Or if you are using the support library, use this:
// getSupportLoaderManager().initLoader(SERVICE_LOADER , null, this);

Categories

Resources