When I implement the GridView in the Fragment instead of the MainActivity class and after I run the app on my phone, the screen is blank. The app fetches the data from the server correctly but does not show anything on the mobile screen.
Here is my MainActivityFragment class :
public class MainActivityFragment extends Fragment {
private GridView gridView;
private GridViewAdapter gridAdapter;
private ArrayList<ImageItem> data;
public MainActivityFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
data = new ArrayList<>();
gridView = (GridView) rootView.findViewById(R.id.gridView);
gridAdapter = new GridViewAdapter(getActivity(), R.layout.grid_poster, data);
gridView.setAdapter(gridAdapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onStart() {
super.onStart();
FetchPosterTask posterTask = new FetchPosterTask();
posterTask.execute();
}
public class FetchPosterTask extends AsyncTask<Void, Void, Integer> {
private final String LOG_TAG = FetchPosterTask.class.getSimpleName();
private Integer parseResult(String result)
throws JSONException{
JSONObject response = new JSONObject(result);
JSONArray movies = response.getJSONArray("results");
ImageItem item = new ImageItem();
for (int i = 0; i < movies.length(); i++) {
JSONObject movie = movies.optJSONObject(i);
item = new ImageItem();
String posterPath = movie.getString("poster_path");
Uri.Builder builder = new Uri.Builder();
builder.scheme("https")
.authority("image.tmdb.org")
.appendPath("t")
.appendPath("p")
.appendPath("w185");
String poster = builder.toString()+posterPath;
item.setImage(poster);
Log.v(LOG_TAG, "poster_path " + poster);
}
data.add(item);
return 1;
}
#Override
protected Integer doInBackground(Void... params) {
Integer result = 0;
HttpURLConnection urlConnection = null;
String moviesJasonStr = null;
String sort_by = "popularity.desc";
BufferedReader reader = null;
try {
final String baseUrl = "http://api.themoviedb.org/3/discover/movie?";
final String QUERY_PARAM = "sort_by";
final String APPID_PARAM = "api_key";
Uri builtUri = Uri.parse(baseUrl).buildUpon()
.appendQueryParameter(QUERY_PARAM, sort_by)
.appendQueryParameter(APPID_PARAM, BuildConfig.OPEN_MOVIES_API_KEY)
.build();
URL url = new URL(builtUri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return 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.
return null;
}
moviesJasonStr = buffer.toString();
Log.v(LOG_TAG, "moviesJasonStr: " + moviesJasonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
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 {
return parseResult(moviesJasonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Integer integer) {
Log.v(LOG_TAG, "result_integer: " + integer);
if (integer == 1) {
gridAdapter.setGridData(data);
} else {
Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
}
}
This is my GridViewAdapter class :
public class GridViewAdapter extends ArrayAdapter<ImageItem> {
private Context context;
private int layoutResourceId;
private ArrayList<ImageItem> data = new ArrayList<ImageItem>();
public GridViewAdapter(Context context, int layoutResourceId, ArrayList<ImageItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
/**
* Updates grid data and refresh grid items.
* #param data
*/
public void setGridData(ArrayList<ImageItem> data) {
this.data = data;
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.image);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
ImageItem item = data.get(position);
//holder.image.setImageBitmap(item.getImage());
Picasso.with(context).load(item.getImage()).into(holder.image);
return row;
}
static class ViewHolder {
ImageView image;
}
}
and this is my fragment_main.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f0f0f0"
tools:context = ".MainActivityFragment">
<GridView
android:id="#+id/gridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:columnWidth="100dp"
android:drawSelectorOnTop="true"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="5dp"
android:focusable="true"
android:clickable="true"/>
</RelativeLayout>
First of all return rootView in onCreate
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
data = new ArrayList<>();
gridView = (GridView) rootView.findViewById(R.id.gridView);
gridAdapter = new GridViewAdapter(getActivity(), R.layout.grid_poster, data);
gridView.setAdapter(gridAdapter);
return rootView;
}
and if its not working then set adapter in onPostexecute
you only has fragment,but fragment need activity to host,you can change this codepublic class MainActivityFragment extends Fragment to public class MainActivityFragment extends FragmentActivity
Related
OnPost Execute method how can I pass image from one Fragment to other activity. Able to pass the image from drawable folder using Bundle. Loding product details from server and able to other information except Image to other Activity.
package sanjay.apackage.torcente.com.torcentemotors;
public class HomeFragment extends Fragment {
FragmentTransaction fragmentTransaction;
//private TextView tvData;
private ListView lvMovies;
public HomeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
//Image loader
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getContext()) //getApplicationContext()
.defaultDisplayImageOptions(defaultOptions)
.build();
ImageLoader.getInstance().init(config); // Do it on Application start
lvMovies = (ListView)view.findViewById(R.id.lvMovies);
new JSONTask().execute("http://torcentemotors.com/app_001/productsInfoNew.php");
return view;
}
public class JSONTask extends AsyncTask<String, String, List<MovieModel> > {
#Override
protected List<MovieModel> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null ) {
buffer.append(line);
}
//return buffer.toString();
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("movies");
List<MovieModel> movieModelList = new ArrayList<>();
for(int i = 0; i< parentArray.length() ;i++ ) {
JSONObject finalObject = parentArray.getJSONObject(i);
MovieModel movieModel = new MovieModel();
movieModel.setProduct_name(finalObject.getString("product_name"));
movieModel.setProduct_price(finalObject.getInt("product_price"));
movieModel.setProduct_image(finalObject.getString("product_image"));
movieModel.setProduct_color(finalObject.getString("product_color"));
movieModel.setCover_image(finalObject.getString("cover_image"));
movieModel.setOriginal_price(finalObject.getInt("original_price"));
movieModel.setApp_desc(finalObject.getString("app_desc"));
//adding the final object to the list
movieModelList.add(movieModel);
}
//return finalBufferedData.toString();
return movieModelList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if( connection != null){
connection.disconnect();
}
try {
if(reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(List<MovieModel> result) {
super.onPostExecute(result);
final MovieAdapter adapter = new MovieAdapter( getActivity().getApplicationContext(), R.layout.rownew, result );
//// getApplicationContext() // getActivity is added by me
lvMovies.setAdapter(adapter);
//set data to list
lvMovies.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Toast.makeText(getActivity().getBaseContext(),parent.getItemIdAtPosition(position)+" is selected",Toast.LENGTH_LONG).show();
MovieModel movieModel = (MovieModel) adapter.getItem(position);
Intent intent = new Intent("sanjay.apackage.torcente.com.torcentemotors.product_details");
//intent.putExtra("product_image", movieModel.getProduct_image());
//sanjay //
intent.putExtra("id",position);
intent.putExtra("product_name",movieModel.getProduct_name());
intent.putExtra("product_price", movieModel.getProduct_price());
intent.putExtra("product_color", movieModel.getProduct_color());
intent.putExtra("original_price", movieModel.getOriginal_price());
intent.putExtra("app_desc", movieModel.getApp_desc());
Bundle bundle=new Bundle();
bundle.putInt("image",R.drawable.ban);
bundle.putInt("image2",R.drawable.fz25);
intent.putExtras(bundle);
startActivity(intent);
}
});
}
}
public class MovieAdapter extends ArrayAdapter{
private List<MovieModel> movieModelList;
private int resource;
private LayoutInflater inflater ;
public MovieAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
movieModelList = objects;
this.resource = resource ;
inflater = (LayoutInflater)context.getSystemService(LAYOUT_INFLATER_SERVICE); // context is added by me.
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
viewHolder holder = null;
if (convertView == null ) {
holder = new viewHolder();
convertView = inflater.inflate(resource, null);
holder.tvIcon = (ImageView)convertView.findViewById(R.id.tvIcon);
holder.tvcover = (ImageView)convertView.findViewById(R.id.tvcover);
holder.tvproduct_name = (TextView)convertView.findViewById((R.id.tvproduct_name));
holder.tvproduct_price = (TextView)convertView.findViewById((R.id.tvproduct_price));
holder.tvproduct_color = (TextView)convertView.findViewById((R.id.tvproduct_color));
holder.tvoriginal_price = (TextView)convertView.findViewById((R.id.tvoriginal_price));
holder.tvapp_desc = (TextView)convertView.findViewById((R.id.tvapp_desc));
convertView.setTag(holder);
} else{
holder = (viewHolder)convertView.getTag();
}
ImageLoader.getInstance().displayImage(movieModelList.get(position).getProduct_image(), holder.tvIcon);
ImageLoader.getInstance().displayImage(movieModelList.get(position).getCover_image(), holder.tvcover);
//holder.tvproduct_id.setText(" Product ID : " +movieModelList.get( position ).getProduct_id());
//holder.tvcategory_id.setText("Category ID : " +movieModelList.get(position).getCategory_id());
//holder.tvsub_category_id.setText("Sub Category ID : " +movieModelList.get(position).getSub_category_id());
holder.tvproduct_name.setText(movieModelList.get(position).getProduct_name());
//holder.tvproduct_code.setText(movieModelList.get(position).getProduct_code());
holder.tvproduct_price.setText("BookingPrice : "+movieModelList.get(position).getProduct_price());
holder.tvproduct_color.setText(movieModelList.get(position).getProduct_color());
holder.tvoriginal_price.setText("Price : "+movieModelList.get(position).getOriginal_price());
//holder.tvapp_desc.setText(movieModelList.get(position).getApp_desc());
return convertView;
}
class viewHolder{
private ImageView tvIcon ;
private ImageView tvcover ;
private TextView tvproduct_id;
private TextView tvcategory_id;
private TextView tvsub_category_id;
private TextView tvproduct_name;
private TextView tvproduct_code;
private TextView tvproduct_color;
private TextView tvproduct_price;
private TextView tvoriginal_price;
private TextView tvapp_desc;
}
}
}
I am developing app just like YOUTUBE. I am getting data from the server and showing it in listview. Because data is too big so i want to restrict list view to 5 items and then when I scroll down to the bottom of listview it should add 5 more item.
I am calling ASyncTask from fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
view = layoutInflater.inflate(R.layout.tab_fragment_2, container, false);
listView = (ListView) view.findViewById(R.id.myList);
New.jsonAsyncTask.execute("my url select_video.php?");
}
Now I have separate JsonAsyncTask Class because I am calling it from 3 fragments just like above mentioned way..
public class JSONAsyncTask extends AsyncTask<String, String, List<SetDatails>> {
ListView listView1;
Context context1;
List<SetDatails> videoLiast1;
private static int tab_id;
public JSONAsyncTask(ListView listView, List<SetDatails> videoLiast,Context context,int id) {
this.listView1 = listView;
this.context1 = context;
this.videoLiast1 = videoLiast;
tab_id=id;
}
#Override
protected List<SetDatails> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader myReader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream myInputStream = connection.getInputStream();
myReader = new BufferedReader(new InputStreamReader(myInputStream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = myReader.readLine()) != null) {
buffer.append(line);
}
String Json_data = buffer.toString();
videoLiast1 = new ArrayList<>();
JSONObject parentObj = new JSONObject(Json_data);
JSONArray dataArray = parentObj.getJSONArray("data");
JSONObject tabObject = dataArray.getJSONObject(tab_id);
JSONArray videoArray = tabObject.getJSONArray("videos");
for (int i = 0; i < videoArray.length(); i++) {
int len=dataArray.length();
SetDatails setDatails = new SetDatails();
JSONObject arrayChild = videoArray.getJSONObject(i);
String vid_ID = arrayChild.getString("id");
setDatails.setVidID(vid_ID);
String movie_title = arrayChild.getString("name");
setDatails.setTitle(movie_title);
String movie_catagory = arrayChild.getString("category_name");
setDatails.setGenre(movie_catagory);
videoLiast1.add(setDatails);
}
return videoLiast1;
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (myReader != null) {
myReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected void onPostExecute(List<SetDatails> videoList) {
super.onPostExecute(videoList);
if(videoList!=null) {
try {
MyListAdapter myListAdapter = new MyListAdapter(context1, videoList);
listView1.setAdapter(myListAdapter);
}catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
I have created an Array adapter to fill list view.
public class MyListAdapter extends ArrayAdapter<SetDatails>{
public static int count =5;
List<SetDatails> videoList;
MyListAdapter(Context context,List<SetDatails> object){
super(context,R.layout.tab2_bookchilds,object);
videoList = object;
}
/**
* {#inheritDoc}
*/
#Override
public int getCount() {
return super.getCount();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater=LayoutInflater.from(getContext());
View view = layoutInflater.inflate(R.layout.tab2_bookchilds, parent, false);
TextView title = (TextView)view.findViewById(R.id.txt_title);
title.setText(videoList.get(position).getTitle());
ImageView imgV_Thumbnail = (ImageView) view.findViewById(R.id.imgV_thumbnail);
Picasso.with(getContext())
.load(videoList.get(position).getThumbnail())
.error(R.drawable.icon_white)
.into(imgV_Thumbnail);
return view;
}
}
I have searched a lot and many people suggest getCount() method although I tried a lot to use this method but don't know how to do that.
Please guys help me because my app is ready to upload but I can't solve this one issue.
I am trying to fetch data using AsyncTask & displaying into a ListView. It never calls getView(), I checked getCount() return always 0.
MainActivityFragment.java
public class MainActivityFragment extends Fragment {
private final String LOG_TAG = MainActivityFragment.class.getSimpleName();
SourceAdapter adapter;
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
adapter = new SourceAdapter(getActivity());
ListView listView = (ListView) rootView.findViewById(R.id.listView);
listView.setAdapter(adapter);
Log.d(LOG_TAG,"after list view set to adapter");
return rootView;
}
#Override
public void onStart() {
new FetchDataTask().execute();
super.onStart();
}
public class FetchDataTask extends AsyncTask<String, Void, SourceObject[]>{
private final String LOG_TAG = FetchDataTask.class.getSimpleName();
private SourceObject[] getSourceDataFromJson(String jsonStr)throws JSONException{
JSONArray jsonArray = new JSONArray(jsonStr);
SourceObject[] sourceObjects = new SourceObject[jsonArray.length()];
for (int i=0; i<jsonArray.length();i++){
sourceObjects[i] = new SourceObject(
jsonArray.getJSONObject(i).getJSONObject("commit").getJSONObject("author").getString("name"),
jsonArray.getJSONObject(i).getJSONObject("commit").getJSONObject("author").getString("name"),
jsonArray.getJSONObject(i).getJSONObject("commit").getString("message")
);
}
return sourceObjects;
}
#Override
protected SourceObject[] doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String jsonStr = null;
try {
String baseUrl = "https://api.github.com/repos/rails/rails/commits";
URL url = new URL(baseUrl);
Log.d(LOG_TAG,"URL IS "+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;
}
jsonStr = buffer.toString();
Log.d(LOG_TAG,"JSON STRING "+jsonStr);
}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(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getSourceDataFromJson(jsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(SourceObject[] strings) {
adapter.notifyDataSetChanged();
super.onPostExecute(strings);
}
}
}
SourceAdapter.java
public class SourceAdapter extends BaseAdapter {
private final String LOG_TAG = SourceAdapter.class.getSimpleName();
Context context;
ArrayList<SourceObject> objects = new ArrayList<SourceObject>();
public SourceAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
Log.d(LOG_TAG,"getCount called "+objects.size());
return objects.size();
}
#Override
public Object getItem(int position) {
Log.d(LOG_TAG,"getItem called");
return objects.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d(LOG_TAG,"get view method is called");
SourceObject sourceObject = (SourceObject) getItem(position);
if (convertView == null){
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item_source,parent,false);
}
TextView personName = (TextView) convertView.findViewById(R.id.person_name);
TextView commit = (TextView) convertView.findViewById(R.id.xxx);
TextView commitMessage = (TextView) convertView.findViewById(R.id.commit_message);
personName.setText(sourceObject.getPersonName());
commit.setText(sourceObject.getCommit());
commitMessage.setText(sourceObject.getCommitMessage());
return convertView;
}
}
Please help.
You are not setting data retrieved from AsyncTask to adapter.
Add this method to your adapter class:
public void setItems(SourceObject[] items) {
this.objects = new ArrayList<SourceObject>();
for(SourceObject item : items){
this.objects.add(item);
}
this.notifyDataSetChanged();
}
And change onPostExecute of AsyncTask to:
#Override
protected void onPostExecute(SourceObject[] strings) {
adapter.setItems(strings);
super.onPostExecute(strings);
}
I'm new to making android apps. I'm trying to make a simple app that pulls movie data from themoviedb.org and displays the posters from the movie on the main page. I'm using GridView and ImageView with a custom adapter but the screen shows up blank. I'm not sure what I need to do to get the images to show up.
Custom adapter:
public class CustomImageAdapter extends BaseAdapter {
private Context mContext;
private String[] inputs;
private List<ImageView> imageList;
LayoutInflater inflater;
public CustomImageAdapter(Context c, String[] inputs) {
mContext = c;
this.inputs = inputs;
inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return inputs.length;
}
public Object getItem(int position) {
return imageList.get(position);
}
public long getItemId(int position) {
return position;
}
public void add(String[] results) {
inputs = results;
imageList = new ArrayList<ImageView>();
for (int i = 0; i < inputs.length; i++){
ImageView imageView = new ImageView(mContext);
Picasso.with(mContext)
.load(inputs[i])
.into(imageView);
imageList.add(imageView);
}
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(mContext);
convertView = inflater.inflate(R.layout.grid_layout, null);
ImageView imageView = (ImageView) gridView.findViewById(R.id.grid_layout_image_view);
imageView = imageList.get(position);
} else {
gridView = (View) convertView;
}
return gridView;
}
}
Main Fragment:
public class GridFragment extends Fragment {
private static ImageView imageView;
private static String[] jsonStringHolder = new String[1];
private static CustomImageAdapter customImageAdapter;
private static GridView gridView;
public GridFragment() {
}
#Override
public void onStart() {
super.onStart();
FetchMovieTask fetchMovieTask = new FetchMovieTask();
fetchMovieTask.execute();
}
private void loadImageView(String[] result) {
try {
getMovieDataFromJson(result);
} catch (JSONException e) {
Log.e("LOG_TAG", e.getMessage(), e);
e.printStackTrace();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//customImageAdapter = new CustomImageAdapter(getContext(), null);
gridView = (GridView) rootView.findViewById(R.id.grid_view);
//gridView.setAdapter(customImageAdapter);
return rootView;
}
private void getMovieDataFromJson(String[] jsonStringHolder)
throws JSONException {
final String OWM_POSTER_PATH = "poster_path";
final String OWM_RESULTS = "results";
String movieJsonStr = jsonStringHolder[0];
JSONObject movieJsonObject = new JSONObject(movieJsonStr);
JSONArray movieJsonArray = movieJsonObject.getJSONArray(OWM_RESULTS);
String[] resultStrs = new String[movieJsonArray.length()];
for (int i = 0; i < movieJsonArray.length(); i++) {
JSONObject movieDescriptionJsonObject = movieJsonArray.getJSONObject(i);
String posterPathPlaceholder =
movieDescriptionJsonObject.getString(OWM_POSTER_PATH);
final String FORECAST_BASE_URL =
"http://api.themoviedb.org/3/movie/";
final String SIZE = "w185";
resultStrs[i] = FORECAST_BASE_URL + SIZE + posterPathPlaceholder;
}
customImageAdapter = new CustomImageAdapter(getContext(), null);
customImageAdapter.add(resultStrs);
gridView.setAdapter(customImageAdapter);
}
public class FetchMovieTask extends AsyncTask<Void, Void, String[]> {
private final String LOG_TAG = FetchMovieTask.class.getSimpleName();
#Override
protected String[] doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String movieJsonStr = null;
// String format = "json";
//String units = "metric";
//int numDays = 7;
try {
// Construct the URL for the OpenWeatherMap query
// Possible parameters are avaiable at OWM's forecast API page, at
// http://openweathermap.org/API#forecast
final String FORECAST_BASE_URL =
"http://api.themoviedb.org/3/movie/";
final String PREFERENCE = "now_playing?";
final String API_KEY = "api_key=e0cbb327025cf835dfc53ca51d11db68";
//final String UNITS_PARAM = "units";
//final String DAYS_PARAM = "cnt";
String urlString = FORECAST_BASE_URL + PREFERENCE + API_KEY;
URL url = new URL(urlString);
// 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.
return 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.
return null;
}
movieJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error pits", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
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);
}
}
}
String[] movieJsonStrArray = new String[1];
movieJsonStrArray[0] = movieJsonStr;
return movieJsonStrArray;
}
#Override
protected void onPostExecute(String[] result) {
if (result != null) {
jsonStringHolder[0] = result[0];
}
loadImageView(result);
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivityFragment">
<GridView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/grid_view"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true">
</GridView>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/grid_layout_image_view" />
</RelativeLayout>
if you are trying to fill a list with rows, and you are new to android, perhaps, you should try extending from ListActivity or FragmentList, see the google guide at http://developer.android.com/guide/topics/ui/layout/listview.html , ListActivity and FragmentList are helper clases, they have a method "setListAdapter" that do the trick.
I seem to have a problem with my ImageAdapter. It should update a GridView but does not do it.
Code:
public class MainActivityFragment extends Fragment {
ImageAdapter imageAdapter;
GridView gridView;
public MainActivityFragment() {
}
#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);
imageAdapter = new ImageAdapter(getActivity(),new ArrayList<Movie>());
gridView.setAdapter(imageAdapter);
return rootView;
}
#Override
public void onStart() {
super.onStart();
UpdateMovies();
}
private void UpdateMovies() {
FetchMoviesTask task = new FetchMoviesTask();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
String sort = preferences.getString(getString(R.string.pref_sort_key), getString(R.string.pref_sort_default));
task.execute(sort);
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Movie> data;
public ImageAdapter(Context c, ArrayList<Movie> movies) {
mContext = c;
data = movies;
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
View gridView;
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
gridView = new GridView(mContext);
gridView = inflater.inflate(R.layout.grid_item_poster, null);
imageView = (ImageView)gridView.findViewById(R.id.poster);
} else {
imageView = (ImageView) convertView;
}
if (data.size() != 0) {
Log.v("IMAGE_ADAPTER","SetView= " + data.get(position).poster);
Picasso.with(mContext).load(data.get(position).poster).into(imageView);
}
return imageView;
}
public void updatePosters(ArrayList<Movie> newMovies) {
data.clear();
data.addAll(newMovies);
this.notifyDataSetChanged();
}
}
public class FetchMoviesTask extends AsyncTask<String, Void, ArrayList<Movie>> {
private final String LOG_TAG = FetchMoviesTask.class.getName();
private ArrayList<Movie> getMovieDataFromJson(String movieJsonStr, int numDays)
throws JSONException {
// These are the names of the JSON objects that need to be extracted.
final String MOV_LIST = "results";
final String MOV_ID = "id";
final String MOV_TITLE = "original_title";
final String MOV_OVERVIEW = "overview";
final String MOV_RATING = "vote_average";
final String MOV_DATE = "release_date";
final String MOV_POSTER = "poster_path";
JSONObject listJson = new JSONObject(movieJsonStr);
JSONArray movieArray = listJson.getJSONArray(MOV_LIST);
ArrayList<Movie> movies = new ArrayList<>();
for(int i = 0; i < movieArray.length(); i++) {
int id;
String title;
String overview;
String rating;
String date;
String poster;
// Get the JSON object representing the day
JSONObject movie = movieArray.getJSONObject(i);
id = movie.getInt(MOV_ID);
title = movie.getString(MOV_TITLE);
overview = movie.getString(MOV_OVERVIEW);
rating = movie.getString(MOV_RATING);
date = movie.getString(MOV_DATE);
poster = movie.getString(MOV_POSTER);
Movie newMovie = new Movie(id, title, overview, rating, date, poster);
movies.add(newMovie);
}
for (Movie s : movies) {
Log.v(LOG_TAG, "Movie entry: " + s.print());
}
return movies;
}
#Override
protected void onPostExecute(ArrayList<Movie> result) {
if(result != null){
Log.v(LOG_TAG,"DATA SET CHANGED! SIZE= " + result.size());
imageAdapter.updatePosters(result);
}
}
#Override
protected ArrayList<Movie> doInBackground(String... params) {
if(params.length == 0){
return null;
}
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String movieJsonStr = null;
String format = "JSON";
String units = "metric";
String apiKey = "********************";
int numDays = 7;
try {
// Construct the URL for the OpenWeatherMap query
// Possible parameters are avaiable at OWM's forecast API page, at
// http://openweathermap.org/API#forecast
final String MOVIE_BASE_URL = "http://api.themoviedb.org/3/discover/movie?";
final String SORT_PARAM = "sort_by";
final String DESC = ".desc";
final String API_PARAM = "api_key";
Uri builtUri = Uri.parse(MOVIE_BASE_URL).buildUpon()
.appendQueryParameter(SORT_PARAM,(params[0]+DESC))
.appendQueryParameter(API_PARAM,apiKey)
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
// 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.
return 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.
return null;
}
movieJsonStr = buffer.toString();
Log.v(LOG_TAG,"Movie JSON String: " + 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 attemping
// to parse it.
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 {
return getMovieDataFromJson(movieJsonStr, numDays);
}catch (JSONException e){
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
}
}
fragment_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivityFragment">
<GridView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/gridView"
android:columnWidth="180dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"/>
grid_item_poster.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:scaleType="centerCrop"
android:id="#+id/poster"
android:adjustViewBounds="true">
</ImageView>
The strange thing is that when I add a ArrayList with elements when I create my ImageAdapter in onCreateView, it does work but when I leave that list unpopulated it does not update.
Anyone got any clue what to do?
Been searching for the solution the whole day now. :D
Thanks in advance.
I have weird impression that something is wrong with your getView() method - I can be wrong but try this one:
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
ImageView imageView;
if (convertView == null) {
convertView = inflater.inflate(R.layout.grid_item_poster, null);
imageView = (ImageView) convertView.findViewById(R.id.poster);
convertView.setTag(imageView);
} else {
imageView = (ImageView) convertView.getTag();
}
if (data.size() != 0 && data.get(position) != null) {
Log.v("IMAGE_ADAPTER","SetView= " + data.get(position).poster);
Picasso.with(mContext).load(data.get(position).poster).into(imageView);
} else {
//I think that you should reset image when there is a issue with data set
imageView.setImageResource(-1);
}
return imageView;
}
Moreover this comment - create a new ImageView for each item referenced by the Adapter is invalid because adapter reuse views, which are outside of the screen, so sometimes instead of creating new instance of ImageView, list displays old one with new data
Edit
Try to create new data list instead of cleaning old one:
public void updatePosters(ArrayList<Movie> newMovies) {
data = new ArrayList<Movies>();
data.addAll(newMovies);
this.notifyDataSetChanged();
}
You getView is not correctly implemented. Firs of all it is very weird what you are trying to achieve there, you are inflating something just to get an ImageView from that layout. You could instead instantiate the ImageView inside the method:
public View getView(int position, View convertView, ViewGroup parent) {
View view=convertView;
if (view == null) {
view=new ImageView(mContext);
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout
.LayoutParams.MATCH_PARENT,LinearLayout
.LayoutParams.WRAP_CONTENT));
view.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
final String url=data.get(position).poster;
if (!TextUtis.isEmpty(url) {
Log.v("IMAGE_ADAPTER","SetView= " + url);
Picasso.with(mContext).load(url).into(((ImageView)view));
} else {
Picasso.with(mContext).load(android.R.color.transparent).into(((ImageView)view);
}
return view;
}