I have pictures from my online database in my GridView and I want it in reverse order.
So I want when I add a new picture to my database to be the first in the GridView.
I tried to find an answer but there is nothing about it at stackoverflow.
This is my ListViewAdapter:
public class GetMovieImagesListViewAdapter extends BaseAdapter {
private JSONArray dataArray;
private Activity activity;
private static final String baseUrlForImage = "http://google.com";
private static LayoutInflater inflater = null;
public GetMovieImagesListViewAdapter(JSONArray jsonArray, Activity a){
this.dataArray = jsonArray;
this.activity = a;
inflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return this.dataArray.length();
}
#Override
public Object getItem(int position){
return position;
}
#Override
public long getItemId(int position){
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ListCell cell;
if (convertView == null) {
convertView = inflater.inflate(R.layout.get_images_from_movies_list_cell, null);
cell = new ListCell();
cell.MovieImages = (ImageView) convertView.findViewById(R.id.movie_images_id);
convertView.setTag(cell);
} else {
cell = (ListCell) convertView.getTag();
}
try {
JSONObject jsonObject = this.dataArray.getJSONObject(position);
String nameOfImage = jsonObject.getString("image");
String urlForImageInServer = baseUrlForImage + nameOfImage;
new AsyncTask<String, Void, Bitmap>(){
#Override
protected Bitmap doInBackground(String... params)
{
String url = params[0];
Bitmap icon = null;
try
{
InputStream in = new URL(url).openStream();
icon = BitmapFactory.decodeStream(in);
} catch (IOException e) {
e.printStackTrace();
}
return icon;
}
#Override
protected void onPostExecute(Bitmap result)
{
cell.MovieImages.setImageBitmap(result);
}
}.execute(urlForImageInServer);
} catch (JSONException e) {
e.printStackTrace();
}
return convertView;
}
private class ListCell{
private ImageView MovieImages;
}}
You could fetch each JSONObject by starting from the end of the array and working backwards to the start:
JSONObject jsonObject = this.dataArray.getJSONObject(getCount() - position - 1);
The result that you have received try to iterate through it in the reverse order.
Your Bitmap result data seems to be a single data that you get. I am expecting an array, or arraylist of data that you get in onPostExecute() method parameter while you query your online database.
Say for example, if you get the data in the form of onPostExecute(ArrayList result), then you can simply iterate the 'result' data in reverse order in order to populate your grid view in reverse order.
Check out Iterate arraylist in reverse order
Related
This is my code:
public class GetAllCategoriesListViewAdapter extends BaseAdapter{
private JSONArray dataArray;
private Activity activity;
private static final String baseUrlForCategoryImage = "link here";
private static LayoutInflater inflater = null;
public GetAllCategoriesListViewAdapter(JSONArray jsonArray, Activity a){
this.dataArray = jsonArray;
this.activity = a;
inflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return this.dataArray.length();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ListCell cell;
if(convertView == null){
convertView = inflater.inflate(R.layout.get_all_categories_list_view_cell, null);
cell = new ListCell();
cell.category_name = (TextView) convertView.findViewById(R.id.category_name);
cell.category_image = (ImageView) convertView.findViewById(R.id.category_image);
cell.category_image.setTag(cell);
convertView.setTag(cell);
}else{
cell = (ListCell) convertView.getTag();
}
try{
JSONObject jsonObject = this.dataArray.getJSONObject(position);
cell.category_name.setText(jsonObject.getString("category_name"));
String nameOfImage = jsonObject.getString("category_image");
String urlForImageInServer = baseUrlForCategoryImage + nameOfImage;
new AsyncTask<String, Void, Bitmap>(){
protected Bitmap doInBackground(String... params){
String url = params[0];
Bitmap icon = null;
try{
InputStream in = new java.net.URL(url).openStream();
icon = BitmapFactory.decodeStream(in);
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
return icon;
}
#Override
protected void onPostExecute(Bitmap result) {
cell.category_image.setImageBitmap(result);
}
}.execute(urlForImageInServer);
}catch (JSONException e){
e.printStackTrace();
}
return convertView;
}
private class ListCell{
private ImageView category_image;
private TextView category_name;
}
}
The code gets the images from my webhost and place it in every cell in my listvew. The problem is everytime I scroll, the images are shuffled and returns in few seconds. How to stop the images from changing when I scroll? I tried to use the solution on other post but it won't work. Please help.
Looks like you are new to android. So you are fetching the images in the getView method. The getView method is called every time a new list item is drawn. So For every image, a new request is made to internet. SO that will be a lot of requests . You should firstly get your images and get them in some ArryayList . Then pass that Arraylist to your adapter. Here is tutorial for you
Using AsyncTask
http://www.devexchanges.info/2015/04/android-custom-listview-with-image-and.html
Using Volley
https://www.androidhive.info/2014/07/android-custom-listview-with-image-and-text-using-volley/
Go for Volley for better performance. Cheers!
I am new to android development,I am parsing my data using JSON Parsing method,I extend my class with List Fragment and I want my data in list view but the problem is i am getting all the data perfectly except the images,i don't know how to solve it,my response looks like this
{"matching":[{"name":"Monic Dano","profile_id":"GM335695","image":"http://mywebsitename.com/images/Girlnoimage.jpg","cast":"","age":"24","location":"Ivory Coast"}]}
public class HomeFragment extends ListFragment {
//CustomAdapter adapter;
//private List<RowItem> rowItems;
private ProgressDialog pDialog;
//JSON parser class
JSONParser jsonParser = new JSONParser();
JSONArray matching=null;
ArrayList<HashMap<String,String>> aList;
private static String MATCH_URL = null;
private static final String TAG_MATCH="matching";
private static final String TAG_NAME="name";
private static final String TAG_PROFILE="profile_id";
private static final String TAG_IMAGE="image";
private static final String TAG_CAST="cast";
private static final String TAG_AGE="age";
private static final String TAG_LOCATION="location";
private ListView listview;
public HomeFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("user_login_id");
MATCH_URL = "http://mywebsitename.com/webservice/matching?version=apps&user_login_id="+strtext;
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
aList = new ArrayList<HashMap<String,String>>();
// rowItems = new ArrayList<RowItem>();
listview=(ListView)rootView.findViewById(android.R.id.list);
new LoadAlbums().execute();
return rootView;
}
class LoadAlbums extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(HomeFragment.this.getActivity());
pDialog.setMessage("Loading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(MATCH_URL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
matching = jsonObj.getJSONArray(TAG_MATCH);
// looping through All Contacts
for (int i = 0; i < matching.length(); i++) {
JSONObject c = matching.getJSONObject(i);
// Storing each json item values in variable
String user_name = c.getString(TAG_NAME);
String user_profile=c.getString(TAG_PROFILE);
String user_image=c.getString(TAG_IMAGE);
String user_cast=c.getString(TAG_CAST);
String user_age=c.getString(TAG_AGE);
String user_location=c.getString(TAG_LOCATION);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_NAME,user_name);
map.put(TAG_PROFILE, user_profile);
map.put(TAG_IMAGE, user_image);
map.put(TAG_CAST, user_cast);
map.put(TAG_AGE, user_age+" years");
map.put(TAG_LOCATION, user_location);
// adding HashList to ArrayList
aList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
protected void onPostExecute(String file_url) {
super.onPostExecute(file_url);
// dismiss the dialog after getting all albums
if (pDialog.isShowing())
pDialog.dismiss();
// updating UI from Background Thread
/**
* Updating parsed JSON data into ListView
* */
// updating listview
CustomAdapter adapter = new CustomAdapter(getActivity(),aList);
setListAdapter(adapter);
}
}
}
Try to AndroidQuery with custom adapter :
public class CustomAdapter extends BaseAdapter {
private Context context;
private ArrayList<HashMap<String,String>> listData;
private AQuery aQuery;
private static final String TAG_NAME="name";
private static final String TAG_PROFILE="profile_id";
private static final String TAG_IMAGE="image";
private static final String TAG_CAST="cast";
private static final String TAG_AGE="age";
private static final String TAG_LOCATION="location";
public CustomAdapter(Context context,ArrayList<HashMap<String,String>> listData) {
this.context = context;
this.listData=listData;
aQuery = new AQuery(this.context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder.propic = (ImageView) convertView.findViewById(R.id.propic);
holder.txtproname = (TextView) convertView.findViewById(R.id.txtproname);
holder.txtproid = (TextView) convertView.findViewById(R.id.txtproid);
holder.txtprofilecast = (TextView) convertView.findViewById(R.id.txtprofilecast);
holder.txtprofileage = (TextView) convertView.findViewById(R.id.txtprofileage);
holder.txtprofileplace = (TextView) convertView.findViewById(R.id.txtprofileplace);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtproname.setText(listData.get(position).get(TAG_NAME));
holder.txtproid.setText(listData.get(position).get(TAG_PROFILE));
holder.txtprofilecast.setText(listData.get(position).get(TAG_CAST));
holder.txtprofileage.setText(listData.get(position).get(TAG_AGE));
holder.txtprofileplace.setText(listData.get(position).get(TAG_LOCATION));
aQuery.id(holder.propic).image(listData.get(position).get(TAG_IMAGE),true,true,0,R.drawable.ic_launcher);
// image parameter : 1 : memory cache,2:file cache,3:target width,4:fallback image
return convertView;
}
class ViewHolder{
ImageView propic;
TextView txtproname;
TextView txtproid;
TextView txtprofilecast;
TextView txtprofileage;
TextView txtprofileplace;
}
}
How to set adapter to ListView :
CustomAdapter adapter = new CustomAdapter(getActivity(),aList);
setListAdapter(adapter);
You can use universal image loader for viewing images from your server.Z
Just pass the image url and your view and you are good to go.
For your reference here is the link to Universal Image loader with all its documentation.
https://github.com/nostra13/Android-Universal-Image-Loader
Hop it helps you.
I am hardly suggest you to use Android Query for this. Its mind blowing api given by Android itself. You can download image, download bitmap or whatever you wanna do you can.
You can download the jar file from here :here Download the jar file and set jar to your Build Path.
AQuery androidAQuery=new AQuery(this);
As an example to load image directly from url:
androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);
As an example to get Bitmap from url:
androidAQuery.ajax(YOUR IMAGE URL,Bitmap.class,0,new AjaxCallback<Bitmap>(){
#Override
public void callback(String url, Bitmap object, AjaxStatus status) {
super.callback(url, object, status);
//You will get Bitmap from object.
}
});
It's very fast and accurate, and using this you can find many more features like Animation when loading; getting a bitmap, if needed; etc.
//Declare adapter globally.
private EfficientAdapter adapter;
//Initialize it in onCreate() method
adapter = new EfficientAdapter(this);
//Set your adapter like
listview.setAdapter(adapter);
//Adapter class code
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Context context;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
}
#Override
public int getCount() {
return aList.size();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.YOUR ITEM LAYOUT, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
holder.txtProfile = (TextView) convertView.findViewById(R.id.txtProfile);
holder.txtCast = (TextView) convertView.findViewById(R.id.txtCast);
holder.txtAge = (ImageView) convertView.findViewById(R.id.txtAge);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(aList.get(position).get(TAG_NAME));
holder.txtProfile.setText(aList.get(position).get(TAG_PROFILE));
holder.txtCast.setText(aList.get(position).get(TAG_CAST));
holder.txtAge.setText(aList.get(position).get(TAG_AGE));
aQuery.id(holder.imgUser).image(data.get(position).get(TAG_IMAGE), true, true);
return convertView;
}
class ViewHolder {
TextView txtName;
TextView txtProfile;
TextView txtCast;
TextView txtAge;
ImageView imgUser;
}
}
In source code of SimpleAdapter:
private void bindView(int position, View view) {
final Map dataSet = mData.get(position);
if (dataSet == null) {
return;
}
final ViewBinder binder = mViewBinder;
final String[] from = mFrom;
final int[] to = mTo;
final int count = to.length;
for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
if (v != null) {
final Object data = dataSet.get(from[i]);
String text = data == null ? "" : data.toString();
if (text == null) {
text = "";
}
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " +
(data == null ? "<unknown type>" : data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleAdapter");
}
}
}
}
}
You can see if your view is ImageView , the code will use the url String be the resId in
/**
* Called by bindView() to set the image for an ImageView but only if
* there is no existing ViewBinder or if the existing ViewBinder cannot
* handle binding to an ImageView.
*
* By default, the value will be treated as an image resource. If the
* value cannot be used as an image resource, the value is used as an
* image Uri.
*
* This method is called instead of {#link #setViewImage(ImageView, int)}
* if the supplied data is not an int or Integer.
*
* #param v ImageView to receive an image
* #param value the value retrieved from the data set
*
* #see #setViewImage(ImageView, int)
*/
public void setViewImage(ImageView v, String value) {
try {
v.setImageResource(Integer.parseInt(value));
} catch (NumberFormatException nfe) {
v.setImageURI(Uri.parse(value));
}
}
And your error is here , so you need Override the getView function of SimpleAdapter.Here is code:
Uri uri = Uri.parse("http://gujjumatch.com/images/Girlnoimage.jpg");
image.setImageURI(uri);
You need to create adapter and extend it to BaseAdapter and add all your items and call it in your AsyncTask's method and it will return your output as said by Haresh Chellana.
I'm stuck creating an Adapter for my Griview that accepts an ArrayList. I think the bad line in the Adapter class is: viewHldr.wcbc_image_iv.setImageResource(urlStrArrList.get(position)); and it appears that the call .setImageResource is the problem.
public class JGrid66 extends Activity {
JSONObject jsonOb;
JSONArray JSArrGallery = null;;
GridView grid65_gv;
JGrid66Adapter2 jGr7Adap;
ProgressDialog mProgressDialog;
ArrayList<String> idStrArrList = new ArrayList<String>();
ArrayList<String> urlStrArrList = new ArrayList<String>();
ArrayList<String> descrStrArrList = new ArrayList<String>();
// JSON Node names
private static final String TAG_GALLERY = "gallery";
private static final String TAG_GALLERYURL = "galleryurl";
private static final String TAG_ID = "id";
private static final String TAG_GALLERYDESCR = "gallerydescr";
static String FLAG = "flag";
private String jsonUrl = "http://www.mysite.com/apps/wcbc/galleryuil.txt";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jgrid66);
grid65_gv = (GridView) findViewById(R.id.jgrid66_gv);
}//--- END onCreate
//--- DownloadJSON Class
private class DownloadJSON extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
JGrid4Adapter jParser = new JGrid4Adapter();
// getting JSON string from URL
JSONObject jsonOb = jParser.getJSONFromUrl(jsonUrl);
try {
JSArrGallery = jsonOb.getJSONArray(TAG_GALLERY);
// looping through All gallery images
for (int i = 0; i < JSArrGallery.length(); i++) {
JSONObject galleryJO = JSArrGallery.getJSONObject(i);
String idStr = galleryJO.getString(TAG_ID);
String urlStr = galleryJO.getString(TAG_GALLERYURL);
String descrStr = galleryJO.getString(TAG_GALLERYDESCR);
idStrArrList.add(idStr);
urlStrArrList.add(urlStr);
descrStrArrList.add(descrStr);
}// -- END for loop
} catch (JSONException e) {
e.printStackTrace();
}// --- END Try
return null;
}
#Override
protected void onPostExecute(Void args) {
jGr7Adap = new JGrid66Adapter2(JGrid66.this, urlStrArrList);
grid65_gv.setAdapter(jGr7Adap);
jGr7Adap.notifyDataSetChanged();
}
}
//--- END DownloadJSON Class
}
Here;s the Adapter:
public class JGrid66Adapter2 extends BaseAdapter {
private ArrayList<String> urlStrArrList;
Context context;
public JGrid66Adapter2(Context context,ArrayList<String> urlStrArrList) {
super();
this.urlStrArrList = urlStrArrList;
}
#Override
public int getCount() {
return urlStrArrList.size();
}
#Override
public String getItem(int position) {
return urlStrArrList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
public static class ViewHolder
{
public ImageView wcbc_image_iv;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHldr;
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
if(convertView==null){
viewHldr = new ViewHolder();
convertView = inflater.inflate(R.layout.jgrid66_item, null);
viewHldr.wcbc_image_iv = (ImageView) convertView.findViewById (R.id.jgrid66_iv);
convertView.setTag(viewHldr);
}
else
{
viewHldr = (ViewHolder) convertView.getTag();
}
//--- I commented this out because this is where it breaks.
//viewHldr.wcbc_image_iv.setImageResource(urlStrArrList.get(position));
return convertView;
}
}
Any help would be great!
private ArrayList<String> urlStrArrList;
is arraylist of strings. If you have the url you need to download the images and then set it to imageview.
setImageResource takes a resource id as a param which is an int value.
public void setImageResource (int resId)
Added in API level 1
Sets a drawable as the content of this ImageView.
You may consider using Lazy Loading Universal Image Loader or using picasso
Caching images and displaying
I'm having some troubles with correct identification of items in a ListView.
There are 4 classes that matter, it's a lot of code so at first I'm going to explain the logic of those classes.
Enter the ListActivity and initialize its ListView
execute an AsyncTask that downloads JSON response from the server, parses it, populates the ListView with Objects and sets the adapter while showing a ProgressDialog
the PlaylistItem class includes methods which simply get the data from a single JSONObject. It is used to parameterize the ArrayList with its Objects
after the AsyncTask is done the list is filled with items and looks like |Button| Artist(TextView) - Title(TextView)
UPDATE
resolved 1st issue but still can't figure out what's wrong with buttons
2). I set an OnClickListener to my buttons in the Adapter's getView() method. To find out if the button is identified correctly I did nothing but just changed its background. BUT a click on a certain button forces the background of every 11th or 12th button to be changed. Can't figure it out so far.
I can't proceed to getting url and streaming audio until those problems are resolved, so any help is greatly appreciated. My classes go below, please ask if something appears unclear.
AudioList
public class AudioList extends ListActivity {
private ListView lv;
private PlaylistLoader loader;
private AudioListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_list);
init(); // initialize the ListView
/*--- populate the list with user's audio in case network connection is available ---*/
loader = new PlaylistLoader(this, lv, adapter);
if (Utils.isNetworkAvailable(this)) {
loader.execute();
} else {
APP_CONSTANTS.NO_DATA_CONNECTION(this);
}
}
#Override
protected void onResume() {
super.onResume();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(getApplicationContext(), Integer.toString(arg2),
Toast.LENGTH_SHORT).show();
}
});
}
private void init() {
lv = getListView();
lv.setTranscriptMode(0x00000000);
lv.setDividerHeight(1);
lv.setSmoothScrollbarEnabled(true);
lv.setVerticalFadingEdgeEnabled(true);
}
PlaylistLoader
public class PlaylistLoader extends AsyncTask<Void, Void, Void> {
private JSONObject usersPlaylist, singleJSONItem;
private JSONArray responseJSONArray;
private ListView lv;
private ArrayList<PlaylistItem> playlist;
private Activity a;
private PlaylistItem audioList;
private SharedPreferences prefs;
private ProgressDialog pd;
AudioListAdapter adapter;
public PlaylistLoader(Activity a, ListView lv, AudioListAdapter adapter) {
this.lv = lv;
this.a = a;
this.adapter = adapter;
}
#Override
protected Void doInBackground(Void... arg0) {
/*--- create new ArrayList of PlaylistItem Objects ---*/
playlist = new ArrayList<PlaylistItem>();
/*--- get the preferences using context of calling activity ---*/
prefs = PreferenceManager.getDefaultSharedPreferences(a);
try {
/*--- download the response JSONObject from server // access_token and
* user_id come from activity's defaultSharedPreferences ---*/
usersPlaylist = Utils.retrieveJsonObjectFromUrl(new URL(
APP_CONSTANTS.REQUEST_AUDIO_LIST(prefs)), a);
/*--- get the response array from received object ---*/
responseJSONArray = usersPlaylist.getJSONArray("response");
/*--- populate the ArrayList with Objects from the response array ---*/
for (int i = 0; i < responseJSONArray.length(); i++) {
singleJSONItem = responseJSONArray.getJSONObject(i);
audioList = new PlaylistItem(singleJSONItem);
playlist.add(audioList);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(a);
pd.setTitle("Please wait");
pd.setMessage("Retrieving audio list...");
pd.show();
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
lv.setVisibility(View.VISIBLE);
pd.dismiss();
/*--- set the adapter passed in constructor as an adapter for passed ListView ---*/
adapter = new AudioListAdapter(a, R.layout.playlist_item, playlist);
lv.setAdapter(adapter);
}
}
AudioListAdapter
public class AudioListAdapter extends ArrayAdapter<PlaylistItem> {
private PlaylistItem pl;
private Context context;
private int layoutResourceId;
private PlaylistItem aud;
private ArrayList<PlaylistItem> data = null;
public AudioListAdapter(Context context, int layoutResourceId,
ArrayList<PlaylistItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public PlaylistItem getItem(int position) {
return super.getItem(position);
}
#Override
public int getCount() {
return data.size();
}
#Override
public int getPosition(PlaylistItem item) {
return super.getPosition(item);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
pl = new PlaylistItem();
aud = getItem(position);
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(layoutResourceId, parent, false);
pl.btnPlay = (Button) convertView.findViewById(R.id.btn_list_play);
pl.imgSaved = (ImageView) convertView
.findViewById(R.id.img_list_audio_saved);
pl.tvArtist = (TextView) convertView
.findViewById(R.id.tvListItemArtist);
pl.tvTitle = (TextView) convertView
.findViewById(R.id.tvListItemSong);
convertView.setTag(pl);
} else {
pl = (PlaylistItem) convertView.getTag();
pl.btnPlay.setBackgroundResource(R.drawable.list_button_play);
}
pl.tvArtist.setText(aud.getArtist() + " " + "-");
pl.tvTitle.setText(aud.getTitle());
pl.btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*--- vibrate if this option is enabled in the preferences ---*/
if (APP_CONSTANTS.isHapticFeedbackEnabled(getContext())) {
APP_CONSTANTS.doVibrate(getContext());
}
pl.btnPlay.setBackgroundResource(R.drawable.list_button_pause);
}
});
return convertView;
}
PlayListItem
public class PlaylistItem {
private String artist, title;
private JSONObject obj;
public Button btnPlay;
public TextView tvArtist, tvTitle;
public ImageView imgSaved;
public int duration;
public int audio_id;
public String url;
/*--- the constructor takes a single JSONObject from the response array ---*/
public PlaylistItem(JSONObject obj) {
this.obj = obj;
}
public PlaylistItem() {
// default constructor
}
/*--- the methods below return values by key from the passed JSONObject ---*/
public String getArtist() {
try {
artist = obj.getString("artist");
} catch (JSONException e) {
e.printStackTrace();
}
return artist;
}
public String getTitle() {
try {
title = obj.getString("title");
} catch (JSONException e) {
e.printStackTrace();
}
return title;
}
public int getID() {
try {
audio_id = obj.getInt("aid");
} catch (JSONException e) {
e.printStackTrace();
}
return audio_id;
}
public String getURL() {
try {
url = obj.getString("url");
} catch (JSONException e) {
e.printStackTrace();
}
return url;
}
}
Edit:
Try this
Take a custom Selector in your drawable
button_play.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/pause_button"
android:state_selected="true" />
<item android:drawable="#drawable/play_button" />
</selector>
Modifty your adapter like this
public class AudioListAdapter extends ArrayAdapter<PlaylistItem> {
private PlaylistItem pl;
private Context context;
private int layoutResourceId;
private PlaylistItem aud;
private ArrayList<PlaylistItem> data = null;
Button previous;
public AudioListAdapter(Context context, int layoutResourceId,
ArrayList<PlaylistItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
previous=new Button(context);
this.context = context;
this.data = data;
}
....
....
#Override
public View getView(int position, View convertView, ViewGroup parent) {
pl = new PlaylistItem();
aud = getItem(position);
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(layoutResourceId, parent, false);
pl.btnPlay = (Button) convertView.findViewById(R.id.btn_list_play);
pl.btnPlay.setBackGroundResouce(R.drawable.button_play); //you can set here or in xml
pl.imgSaved = (ImageView) convertView
.findViewById(R.id.img_list_audio_saved);
pl.tvArtist = (TextView) convertView
.findViewById(R.id.tvListItemArtist);
pl.tvTitle = (TextView) convertView
.findViewById(R.id.tvListItemSong);
convertView.setTag(pl);
} else {
pl = (PlaylistItem) convertView.getTag();
}
pl.tvArtist.setText(aud.getArtist() + " " + "-");
pl.tvTitle.setText(aud.getTitle());
pl.btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*--- vibrate if this option is enabled in the preferences ---*/
if (APP_CONSTANTS.isHapticFeedbackEnabled(getContext())) {
APP_CONSTANTS.doVibrate(getContext());
}
//for some reason, the background gets changed for every 11th or 12th button in the list
Button current=((Button)v);
current.setSelected(true);
previous.setSelected(false);
previous=current;
}
});
return convertView;
}
}
The reason why your button and listitem not clickable is because Your list have a focus item button, so you need to setFocusable=false for your button.
Try setting focusable=false for your button in the xml. If it is not worked for you than do like this
In your row xml file
1.set focusable=true for your button.
2.In the same set android:descendantFocusability="blocksDescendants" for your parent item.(i.e parent layout in which your views lie).
In getView() method after setting the onclickListener for the button, set focusable false for the button.
It will work for sure. I hope this will help you..
BUT a click on a certain button forces the background of every 11th or 12th button to be changed. Can't figure it out so far.
You are fighting the way ListViews recycle the row layouts.
Think of it this way: if you have a ListView with 10,000 rows but can only fit 9 of them on the screen, then it doesn't make sense to create 10,000 unique layouts. This just waste resources, instead ListView only creates ~10 layouts and reuses them.
Solution: return each row to it's default state when it is reused. In getView() add:
} else {
pl = (PlaylistItem) convertView.getTag();
pl.btnPlay.setBackgroundResource(R.drawable.list_button_play);
// I guessed at the resource's name ^^^^^^^^^^^^^^^^
}
(Also you can make a few small changes to speed up your code. For instance, you only need one OnClickListener since they all contain the same code, make this a class variable and pass this to each play Button. There are more.)
this is gridview that get image from json. I successfully with it. But when I get it from server it has a lot of images, that mean all images from server. I want to once load is 12 images.
How can I limit number of images to load?
Please help me briefly because I blind with lazy loading. If the code below not not enough. here is full source http://pastie.org/5583485
in this url, 50 is a number of image to load, i can limit number of image by this value whatever i want. but i just can load once time, so i can't load it more. this url provide image path as json.
String url = "http://xxx.xxx.xxx/card/all/50/0/?token=57LzEsmBeykLbDCD04wTgK9WWV2XjJY0XBdqVU0HQvjIdu5EtTWOT1IQ1AYNwxt6Q5bG6FG73uvzLQSDGAIezwc8VcopEp0s63uzbdVgLSfts0TLmuVDOgyfn4lX";
doInBackground of asynctask
public class DownloadJSONFileAsync extends AsyncTask<String, Void, Void> {
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
}
#Override
protected Void doInBackground(String... params) {
String url = "http://rest.mcolle.com/card/all/50/0/?token=57LzEsmBeykLbDCD04wTgK9WWV2XjJY0XBdqVU0HQvjIdu5EtTWOT1IQ1AYNwxt6Q5bG6FG73uvzLQSDGAIezwc8VcopEp0s63uzbdVgLSfts0TLmuVDOgyfn4lX";
JSONArray data = null;
try {
JSONObject jsonObject = new JSONObject(getJSONUrl(url));
MyArrList = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map;
data = jsonObject.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
JSONObject c = data.getJSONObject(i);
map = new HashMap<String, Object>();
// Thumbnail Get ImageBitmap To Object
map.put("cardimage", (String) c.getString("cardimage"));
map.put("ImageThumBitmap",(Bitmap) loadBitmap(c.getString("cardimage")));
map.put("categoryid", (String) c.getString("categoryid"));
MyArrList.add(map);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void unused) {
ShowAllContent(); // When Finish Show Content
dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
}
ImageAdpater where i show image
public class ImageAdapter extends BaseAdapter {
private Context context;
private ArrayList<HashMap<String, Object>> MyArr = new ArrayList<HashMap<String, Object>>();
public ImageAdapter(Context c, ArrayList<HashMap<String, Object>> myArrList) {
context = c;
MyArr = myArrList;
}
public int getCount() {
return MyArr.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.grid_item, null);
}
viewHolder.categoryCard = (ImageView) convertView.findViewById(R.id.category_card);
viewHolder.categoryCard.setImageResource(R.drawable.card_etc);
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView1);
try {
viewHolder.imageView.setImageBitmap((Bitmap) MyArr.get(position).get("ImageThumBitmap"));
} catch (Exception e) {
viewHolder.imageView.setImageResource(android.R.drawable.ic_menu_report_image);
}
return convertView;
}
}
you can use universal image loader ,
https://github.com/nostra13/Android-Universal-Image-Loader