Please bear with me before downvoting this.I am a beginner to Android. After trying multiple solutions on here I have failed to resolve this.
I am trying to set the Image in the listview with the following items in place.I want to be able to insert the image code somewhere on the Schedule adapter class.
The following code is my Schedule Adapter
public class Schedule_ArrayAdapter extends ArrayAdapter<String> {
private final Activity activity;
private final String[] name, category, image;
Typeface colab, colab_bold, Bebas;
int selected = -1;
public Schedule_ArrayAdapter(Activity activity, String[] name, String[] category, String[] image) {
super(activity, R.layout.schedule_item, category);
this.activity = activity;
this.name = name;
this.category = category;
this.image = image;
this.colab = Typeface.createFromAsset(activity.getAssets(), "ColabThi.otf");
this.colab_bold = Typeface.createFromAsset(activity.getAssets(), "ColabMed.otf");
this.colab_bold = Typeface.createFromAsset(activity.getAssets(), "BebasNeue.otf");
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//get view and textview from xml
View rowView = inflater.inflate(R.layout.schedule_item, parent, false);
rowView.setBackgroundColor(0xffffffff);
LinearLayout background = (LinearLayout) rowView.findViewById(R.id.back);
if (selected != -1) {
if (selected == position) {
background.setBackgroundColor(0xffeaac4b);
} else {
background.setBackgroundColor(0xffffffff);
}
}else{
background.setBackgroundColor(0xffffffff);
}
TextView TimeView = (TextView) rowView.findViewById(R.id.category);
TextView TitleView = (TextView) rowView.findViewById(R.id.title);
ImageView vi = (ImageView) rowView.findViewById(R.id.imgPreview);
GetImage getimage = new GetImage();
getimage.execute(image);
//change names
TitleView.setText(category[position]);
TitleView.setTextSize(fontpercent_screenheight(3.5));
TitleView.setPadding(dp(10), dp(5), dp(5), dp(0));
TitleView.setTypeface(Bebas);
TimeView.setText(name[position]);
TimeView.setTextSize(fontpercent_screenheight(3.5));
TimeView.setPadding(dp(10), dp(2), dp(5), dp(5));
TimeView.setTypeface(colab);
return rowView;
}
The following is my ImageDownloader class
public class ImageDownloader {
private InputStream OpenHttpConnection(String image) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(image);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
conn.setUseCaches(true);
HttpURLConnection httpConn = (HttpURLConnection) conn;
try {
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting" + ex);
}
return in;
}
public Bitmap DownloadImage(String image) {
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(image);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return bitmap;
}
}
Parsing of JSON and fetching Data is working as normal. When looking in the debugger the "image" array is also been fetched. How do i set the images in the view ?
So in your getView of the adapter you should make a request to some url and use the
Bitmap bitmap=BitmapFactory.decodeStream(inputstream);
now set this in your imageview of your layout
ImageView i=(ImageView)findViewById(R.id.imageiew);
i.setImageResource(bitmap);
so that shows the image.
You can also try this code
ImageView iv=(ImageView) findViewById(R.id.imageview);
try {
iv.setImageDrawable(grabImageFromUrl(Global.a5));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
the function of fetching image from URL is
private Drawable grabImageFromUrl(String url) throws Exception {
return Drawable.createFromStream((InputStream)new URL(url).getContent(), "src"); }
Related
I am tying to lazy load images into my ListView, the images are loading fine, but I've a problem. While loading the images get interchanged.
Let's say that the ListView has 10 rows. It loads the images for 1st row, it displays it in the 1st row, then it loads the image for the 2nd row. It displays in the 2nd row for a moment and then it displays the image for the 2nd row in the 1st row. Then the ImageView in row1 switches between images of 1st row and 2nd. Similarly while loading images of next rows. the previous row's images get switched between. And then after loading all the images, everything gets displayed correctly.
Here's my code
Adapater class:
public class FamilyMemberListAdapter extends ArrayAdapter<Map<String, String>> {
List<Map<String, String>> familyMemberList = new ArrayList<Map<String, String>>();
private Activity activity;
public FamilyMemberListAdapter(Activity activity,
List<Map<String, String>> familyMemberList) {
super(activity, R.layout.activity_gch_family_members, familyMemberList);
this.activity = activity;
this.familyMemberList = familyMemberList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(this.getContext()).inflate(
R.layout.activity_gch_family_member_item, parent, false);
holder = new ViewHolder();
holder.lblFamilyMemberName = (TextView) convertView
.findViewById(R.id.lblFamilyMemberItem);
holder.lblFamilyMemberRelation = (TextView) convertView
.findViewById(R.id.lblFamilyMemberRelationItem);
holder.imgProfilePic = (ImageView) convertView
.findViewById(R.id.imgvProfilePic);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
int accountId = Integer.valueOf(familyMemberList.get(position).get(
"accountId"));
holder.lblFamilyMemberName.setText("Name: "
+ familyMemberList.get(position).get("name"));
holder.lblFamilyMemberRelation.setText("Relation: "
+ familyMemberList.get(position).get("relation"));
if (holder.imgProfilePic != null) {
new ImageDownloaderTask(holder.imgProfilePic).execute(String
.valueOf(accountId));
}
return convertView;
}
#Override
public int getCount() {
return familyMemberList.size();
}
static class ViewHolder {
TextView lblFamilyMemberName;
TextView lblFamilyMemberRelation;
ImageView imgProfilePic;
}
}
Imageloader AsyncTask:
public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
protected Bitmap doInBackground(String... params) {
String responseText = null;
HttpClient httpClient = ServiceHelper.getHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(RestApiPaths.GET_PROFILE_PIC + accountId);
try {
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
// getting contents from the stream
inputStream = entity.getContent();
// decoding stream data back into image Bitmap that android understands
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
Log.d(TAG, responseText);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
Drawable placeholder = imageView.getContext().getResources().getDrawable(R.drawable.holder_pic_side);
imageView.setImageDrawable(placeholder);
}
}
}
}
}
I've created a Static class for the ListView items. Still Why is the images go on interchanging while loading. Please tell me what I'm doing wrong here.
Add holder.imgProfilePic.setTag(accountId); before you call the AsyncTask. Add an extra parameter accountId to your task. Then in onPostExecute check if it is the same accountId as in the image view
Maybe try to use libraries like picasso or universal image loader or something.
They have solved most of problems with image loading
Not all images are displaying when running my app. I am getting from json this result
{"result":[{"id":"1","name":null,"path":"http://api.androidhive.info/json/movies/1.jpg"},{"id":"2","name":null,"path":"http://www.justedhak.comlu.com/images/uploaded_images.jpg"},{"id":"32","name":null,"path":"http://www.justedhak.comlu.com/images/uploaded_images.jpg"},{"id":"31","name":null,"path":"http://www.justedhak.comlu.com/images/uploaded_images.jpg"},{"id":"30","name":null,"path":"http://www.justedhak.comlu.com/images/uploaded_images.jpg"},{"id":"29","name":null,"path":"http://www.justedhak.comlu.com/images/uploaded_images.jpg"}]}
the first 2 url images are displaying correctly in the app however the rest of the url are not displaying
these are working
[{"id":"1","name":null,"path":"http:\api.androidhive.info\json\movies\1.jpg"},{"id":"2","name":null,"path":"http:\justedhak.comlu.com\images\uploaded_images.jpg"}
these is my code of reading the image
//showlist() is under asynctask prePostExecute
protected void showList(){
try {
JSONObject jsonObj = new JSONObject(myJSON);
peoples = jsonObj.getJSONArray(TAG_RESULTS);
for(int i=0;i<peoples.length();i++){
JSONObject c = peoples.getJSONObject(i);
String id = c.getString(TAG_ID);
String url = c.getString(TAG_PATH);
Listitem.add(new Listitem(id,url));
}
GridViewAdapter adapter = new GridViewAdapter(this, R.layout.grid_item_layout, Listitem);
// gridView.setAdapter(gridAdapter);
list.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
public class GetDataJSON extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost("http://justedhak.comlu.com/get-data.php");
// Depends on your web service
httppost.setHeader("Content-type", "application/json");
InputStream inputStream = null;
String result = null;
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
// Oops
}
finally {
try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
}
return result;
}
I guess my error is here grid view adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null) {
LayoutInflater inflater = LayoutInflater.from(mcontext);
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.imageTitle = (TextView) row.findViewById(R.id.text);
holder.imageView = (ImageView) row.findViewById(R.id.imageView);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
Listitem item = getItem(position);
System.out.println(item.getUrl());
holder.imageTitle.setText(item.getId());
Picasso.
with(mcontext).
load(item.getUrl())
.placeholder(R.drawable.ic_launcher)
.fit()
.into(holder.imageView);
return row;
}
static class ViewHolder {
TextView imageTitle;
ImageView imageView;
}
}
upload
public void upload()
{
Calendar thisCal = Calendar.getInstance();
thisCal.getTimeInMillis();
// android.util.Log.i("Time Class ", " Time value in millisecinds "+ thisCal);
// Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
// ByteArrayOutputStream stream = new ByteArrayOutputStream();
// bmp.compress(Bitmap.CompressFormat.PNG, 90, stream); //compress to which format you want.
Intent intent = getIntent();
String selectedImage= intent.getStringExtra("imagePath");
Uri fileUri = Uri.parse(selectedImage);
// Uri selectedImage = intent.getData();
System.out.println(fileUri);
InputStream imageStream = null;
try {
imageStream = getContentResolver().openInputStream(fileUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bmp = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 30, stream);
byte[] byteArray = stream.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
imageview.setImageBitmap(bitmap);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
System.out.println(width);
System.out.println(height);
getResizedBitmap( bitmap, 200);
try {
stream.close();
stream = null;
} catch (IOException e) {
e.printStackTrace();
}
String image_str = Base64.encodeBytes(byteArray);
final ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("image",image_str));
nameValuePairs.add(new BasicNameValuePair("caption",caption));
nameValuePairs.add(new BasicNameValuePair("name","je"));
nameValuePairs.add(new BasicNameValuePair("categorie",categorie));
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://justedhak.comlu.com/images/upload_image.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
final String the_string_response = convertResponseToString(response);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(AddImage.this, "Response " + the_string_response, Toast.LENGTH_LONG).show();
}
});
}catch(final Exception e){
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(AddImage.this, "ERROR " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
System.out.println("Error in http connection "+e.toString());
}
}
});
t.start();
}
Getting reference for GridView sample from here, I have just customized and tested loading all your images with it.
Item.java:
public class Item {
String imageUrl;
String title;
public Item(String imageUrl, String title) {
super();
this.imageUrl = imageUrl;
this.title = title;
}
public String getImageUrl() {
return imageUrl;
}
public String getTitle() {
return title;
}
}
CustomGridViewAdapter.java:
public class CustomGridViewAdapter extends ArrayAdapter<Item> {
Context context;
int layoutResourceId;
ArrayList<Item> data = new ArrayList<>();
public CustomGridViewAdapter(Context context, int layoutResourceId,
ArrayList<Item> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
RecordHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new RecordHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.item_text);
holder.imageItem = (ImageView) row.findViewById(R.id.item_image);
row.setTag(holder);
} else {
holder = (RecordHolder) row.getTag();
}
Item item = data.get(position);
holder.txtTitle.setText(item.getTitle());
Picasso.with(context).load(item.getImageUrl()).into(holder.imageItem);
return row;
}
static class RecordHolder {
TextView txtTitle;
ImageView imageItem;
}
}
And MainActivity.java:
customGridAdapter = new CustomGridViewAdapter(this, R.layout.row_grid, gridArray);
gridView.setAdapter(customGridAdapter);
String url = "http://justedhak.comlu.com/get-data.php";
RequestQueue queue = Volley.newRequestQueue(mContext);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (response != null && !response.isNull("result")) {
try {
JSONArray jsonArray = response.getJSONArray("result");
if (jsonArray != null && jsonArray.length() > 0) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
if (jsonObject != null && !jsonObject.isNull("path")) {
String imagePath = jsonObject.getString("path");
if (imagePath != null && !imagePath.isEmpty()) {
gridArray.add(new Item(imagePath,"BNK"));
}
}
}
customGridAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
});
queue.add(jsonObjectRequest);
Other files such as layout... I think you know already
Here is the screenshot
As per my study It's a bug that is reported to be fixed in the next release of the lib.
You can clone the repo of the lib and compile your own jar or wait.
I recommend you to take a look at Glide. Migrating from Picasso is quite trivial, it has better performance and it makes a nice smooth scrolling on lists.
Or try to remove .fit() from picasso.
Picasso.
with(mcontext).
load(item.getUrl())
.placeholder(R.drawable.ic_launcher)
.into(holder.imageView);
Hope it will help you.
You should normalize your Uri cause this seems to be to problem here.
Take a look at normalizeScheme() of the Uri class.
It fixes such problems regargng to upper/lowercase letters.
It will convert:
Http:\justedhak.comlu.com\images\uploaded_images.jpg
to
http:\justedhak.comlu.com\images\uploaded_images.jpg
If you want some more details you can take a look at this RFC 2396
Scheme names consist of a sequence of characters beginning with a
lower case letter and followed by any combination of lower case
letters[...]
I'm trying to handle an image loading at the background.
Now, I've look at the next link - here
And I've got few things I don't understand -
1) I've made the next CursorAdapter for the listview items-
public class ChatCursorAdapter extends CursorAdapter implements OnClickListener {
public ChatCursorAdapter(Context context, Cursor c) {
super(context, c, 0);
}
#Override
public int getCount() {
return getCursor() == null ? 0 : super.getCount();
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int _position) {
Cursor cursor = (Cursor) getItem(_position);
return getItemViewType(cursor);
}
private int getItemViewType(Cursor cursor) {
String sender = cursor.getString(2);
SharedPreferences userPref = PreferenceManager
.getDefaultSharedPreferences(MainChat.this);
String saveUser = userPref.getString("user", "");
if (saveUser.equalsIgnoreCase(sender)){
return 0;
}else{
return 1;
}
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
holder = (ViewHolder) view.getTag();
holder.mesg.setText(getSmiledText(MainChat.this,msg));
holder.mesg2.setText(getSmiledText(MainChat.this,msg2));
holder.myImage.setTag(picPath);
holder.myImage.setImageBitmap(setImageToImageView(picPath));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
View itemLayout = null;
switch(getItemViewType(cursor)){
case 0:
itemLayout = getLayoutInflater().inflate(R.layout.msg_item1,parent, false);
break;
case 1:
itemLayout = getLayoutInflater().inflate(R.layout.msg_item13, parent,false);
break;
}
itemLayout.setTag(holder);
holder.mesg = (TextView) itemLayout.findViewById(R.id.text_start);
holder.mesg2 = (TextView) itemLayout.findViewById(R.id.text_end);
holder.myImage = (ImageView) itemLayout.findViewById(R.id.imageView_msgpic);
return itemLayout;
}
Now i wnat to use the info from the link.
But i don't understand - What i need to pass into the and what to AsyncTask leave at CursorAdapter?
Also the sample code uses -
.execute(holder);
Can't I call to the AsyncTask like this -
new AsyncTask().execute();
And how and where should i call the AsyncTask, I don't understand it?
Thanks for any kind of help
You could always use an external lib like Universal-Image-Loader or Picasso to achieve what you are trying to do =)
Take a look at AsyncTask. You must Override doInBackground method. You may define a constructor to supply view in which you want to put downloaded image.
public class ImageDownloader extends AsyncTask<String, Void, List<Bitmap>> {
private ImageView ivImageHolder;
private Context context;
public ImageDownloader(Context context, ImageView imageHolder) {
this.ivImageHolder = imageHolder;
this.context = context;
}
...
#Override
protected List<Bitmap> doInBackground(String... params) {
//This happens in background
List<Bitmap> bitmaps = new ArrayList<Bitmap>();
for (String url : params) {
Bitmap bitmap = DownloadImage(url);
bitmaps.add(bitmap);
}
return bitmaps;
}
....
private Bitmap DownloadImage(String URL) {
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return bitmap;
}
...
private InputStream OpenHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting");
}
return in;
}
#Override
protected void onPostExecute(List<Bitmap> bitmaps) {
super.onPostExecute(bitmaps);
for (int i = 0; i < bitmaps.size(); i++) {
final Bitmap bitmap = bitmaps.get(i);
ivImageHolder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new ImageViewActivity(context, bitmap).show();
}
});
// iv.setImageBitmap(bitmap);
ivImageHolder.setImageBitmap(bitmap);
ivImageHolder.setVisibility(ImageView.VISIBLE);
}
}
if you write your asyntask method I can say how can you use it, If it need to string value
you can use like this:
new your_async(context).execute(url) ;
But in my advice : you should use lazyadapter to use bitmaps on listview because there is a mermory issue if you do not pay attention properties of images.
here is link : stackoverfow
i want to display images from mysql server(testing in localhost) using imageurl,i have images in a filder on my server,in an android client app as gridview along with text.how do i use imageurl in my code?
mymainmenu.java
public class MainMenu extends Activity {
GridView gridView;
static final String[] MOBILE_OS = new String[] {
"Android", "iOS","Windows", "Blackberry" };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainmenu_list);
gridView = (GridView) findViewById(R.id.gridView1);
gridView.setAdapter(new ImageAdapter(this, MOBILE_OS));
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(
getApplicationContext(),
((TextView) v.findViewById(R.id.grid_item_label))
.getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
my imageadapter.java:
public class ImageAdapter extends BaseAdapter {
private Context context;
private final String[] mobileValues;
public ImageAdapter(Context context, String[] mobileValues) {
this.context = context;
this.mobileValues = mobileValues;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// get layout from list.xml
gridView = inflater.inflate(R.layout.list, null);
// set value into textview
TextView textView = (TextView) gridView
.findViewById(R.id.grid_item_label);
textView.setText(mobileValues[position]);
// set image based on selected text
ImageView imageView = (ImageView) gridView
.findViewById(R.id.grid_item_image);
String mobile = mobileValues[position];
if (mobile.equals("Windows")) {
imageView.setImageResource(R.drawable.imggrid);
} else if (mobile.equals("iOS")) {
imageView.setImageResource(R.drawable.imggrid);
} else if (mobile.equals("Blackberry")) {
imageView.setImageResource(R.drawable.imggrid);
} else {
imageView.setImageResource(R.drawable.imggrid);
}
} else {
gridView = (View) convertView;
}
return gridView;
}
#Override
public int getCount() {
return mobileValues.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
I dnt know how to use the following in my code:
try {
URL url = new URL(imageFileURL);
URLConnection conn = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection)conn;
httpConn.setRequestMethod("GET");
httpConn.connect();
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpConn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
inputStream.close();
img.setImageBitmap(bitmap);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Put the image downloading code in a AsyncTask. Here is the explanation.
Execute one instance of asynctask in your getView method, i.e to fetch one image everytime.
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView mImageView;
public void setImageView(ImageView img) {
mImageView = img;
}
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
Call task.setImageView(yourImageViewinGrid) before executing your AsyncTask to let it know where to set the image after downloading.
To get the image, you have to do something like :
URL new_url = new URL("your url");
Bitmap image_bitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); ImageView image_view = new ImageView(this);
image_view.setImageBitmap(image_bitmap);
Anyway, it's better to download the image as background task. What I actually do is to create a custom view with one private inner class that extend AsyncTask to download the image for you.
I dnt know how to use the following in my code:
that code will download the image for you, you can place in separate thread either AsyncTask or Thread and set the downloaded image in the imageview... simple as that. There are so many example on the web you can google it out
EIDTED
code to download the image
public class AsyncFetchImage extends AsyncTask<String, Void, Bitmap>{
private WeakReference<ImageView> imageReference;
// private WeakReference<Dialog> dialogReferance;
public AsyncFetchImage(ImageView imageview) {
imageReference = new WeakReference<ImageView>(imageview);
// dialogReferance = new WeakReference<Dialog>(dialog);
}
#Override
protected Bitmap doInBackground(String... s) {
return downloadImage(s[0]);
}
private Bitmap downloadImage(String url) {
final AndroidHttpClient client = AndroidHttpClient.newInstance("Nixit");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if(statusCode != HttpStatus.SC_OK){
Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if(entity != null){
InputStream is = null;
try{
is = entity.getContent();
final Bitmap bit = BitmapFactory.decodeStream(is);
return bit;
}finally{
if(is != null)
is.close();
entity.consumeContent();
}
}
} catch (IOException e) {
e.printStackTrace();
return null;
} finally{
if(client != null){
client.close();
}
}
Log.i("Image Fetch","Image Fetch Complete");
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
if(isCancelled()){
result = null;
}
if(imageReference != null){
ImageView imageView = imageReference.get();
// Dialog di = dialogReferance.get();
if (imageView != null) {
imageView.setImageBitmap(result);
// di.show();
}
}
}
}
How to use:-
imageView = (ImageView)dialog.findViewById(R.id.imageView1);
AsyncFetchImage fetchImage = new AsyncFetchImage(imageView);
fetchImage.execute(url);
You can use this in getview method of adapter
Hope that help
I'm working on a small project on Android and have a serious problem with implementing some multi-threading into my solution. Below is a class that is an activity inside the tab of the main interface, which displays a custom list with pictures and data downloaded from YouTube API.
The class works fine, but it completely blocks the UI when, first the data, and then the images are being loaded from the Internet. I know I need to implement some threading and I have tried various things, but I'm not quite sure which parts of the code I have to launch as separate threads. There's also a chance there is something fundamentally wrong with my code structure.
Ideally I'd like to have the UI shown to the user immediately after the application is launched with a progress dialog on top of it, while the textual data is being loaded from YouTube. Then the user should get control of the UI, while images are being loaded in another thread in the background.
public class VodsActivity extends ListActivity {
private LayoutInflater mInflater;
private Vector<RowData> data;
RowData rd;
//private Handler mHandler;
private ProgressDialog dialog;
//Generic names of custom ListView elements
private static String[] title;
private Vector<String> detail;
private Vector<String> status;
private Vector<String> imgurl;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_list);
mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
title = getResources().getStringArray(R.array.yt_channels);
detail = new Vector<String>();
status = new Vector<String>();
imgurl = new Vector<String>();
//mHandler = new Handler();
//dialog = ProgressDialog.show(VodsActivity.this, "","Loading. Please wait...", true);
loadData();
displayData();
//dialog.dismiss();
}
private void loadData() {
String[] values = {"error", "error", "http://www.ephotobay.com/thumb/message-error.jpg" };
for (int i = 0; i < title.length; i++) {
values = getData(title[i]);
values[1] = getTodaysUploads(title[i]);
detail.add(i, values[0]);
status.add(i, values[1]);
imgurl.add(i, values[2]);
}
}
/*** This function gets total number of uploads and thumbnail url for the user from a single feed ***/
private String[] getData (String username) {
String[] result = new String[3];
String ytFeedUrl = "http://gdata.youtube.com/feeds/api/users/" + username + "?v=2";
InputStream inStream = null;
try {
inStream = OpenHttpConnection(ytFeedUrl);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(inStream);
Element docEle = dom.getDocumentElement();
inStream.close();
NodeList nl = docEle.getElementsByTagName("entry");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
Element entry = (Element) nl.item(i);
Element thumbnail = (Element) entry.getElementsByTagName("media:thumbnail").item(0);
String thumbUrl = thumbnail.getAttribute("url");
Element feedLink = (Element) entry.getElementsByTagName("gd:feedLink").item(5);
String uploads = feedLink.getAttribute("countHint");
result[0] = uploads + " videos";
result[1] = ""; //not used here
result[2] = thumbUrl;
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
finally {
//
}
return result;
}
/*** This function gets a number of today's uploads of the user ***/
private String getTodaysUploads (String username) {
String result = null;
String ytFeedUrl = "http://gdata.youtube.com/feeds/api/videos?author=" + username + "&time=today&v=2";
InputStream inStream = null;
try {
inStream = OpenHttpConnection(ytFeedUrl);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(inStream);
Element docEle = dom.getDocumentElement();
inStream.close();
NodeList nl = docEle.getElementsByTagName("feed");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
Element entry = (Element) nl.item(i);
Element title = (Element)entry.getElementsByTagName("openSearch:totalResults").item(0);
result = title.getFirstChild().getNodeValue();
result += " new today";
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
finally {
//
}
return result;
}
private void displayData () {
//Use vector instead of ArrayList for safe threading
data = new Vector<RowData>();
for (int i = 0; i < title.length; i++) { //Loop needs to be changed based on results
try {
rd = new RowData(i, title[i], detail.get(i), status.get(i));
} catch (Exception e) {
e.printStackTrace();
}
data.add(rd);
}
CustomAdapter adapter = new CustomAdapter (this, R.layout.custom_list_item, R.id.title, data);
setListAdapter(adapter);
getListView().setTextFilterEnabled(true);
}
private InputStream OpenHttpConnection(String strUrl) throws IOException {
InputStream inStream = null;
URL url = new URL(strUrl);
URLConnection conn = url.openConnection();
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setRequestMethod("GET");
httpConn.connect();
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
inStream = httpConn.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return inStream;
}
//This is temporary
public void onListItemClick(ListView parent, View v, int position, long id) {
CustomAdapter adapter = (CustomAdapter) parent.getAdapter();
RowData row = adapter.getItem(position);
Builder builder = new AlertDialog.Builder(this);
builder.setTitle(row.mTitle);
builder.setMessage(row.mDetail + " -> " + position );
builder.setPositiveButton("ok", null);
builder.show();
}
//Private class RowData - holds details of CustomAdapter item
private class RowData {
protected int mId;
protected String mTitle;
protected String mDetail;
protected String mStatus;
RowData (int id, String title, String detail, String status) {
mId = id;
mTitle = title;
mDetail = detail;
mStatus = status;
}
#Override
public String toString() {
return mId + " " + mTitle + " " + mDetail + " " + mStatus;
}
}
//Custom Adapter for the custom list, overrides onView() method
private class CustomAdapter extends ArrayAdapter<RowData> {
public CustomAdapter(Context context, int resource, int textViewResourceId, List<RowData> objects) {
super (context, resource, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
TextView title = null;
TextView detail = null;
TextView status = null;
ImageView image = null;
RowData rowData = getItem(position);
//Reuse existing row views
if(convertView == null) {
convertView = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
title = holder.getTitle();
title.setText (rowData.mTitle);
detail = holder.getDetail();
detail.setText(rowData.mDetail);
status = holder.getStatus();
status.setText(rowData.mStatus);
//add if statements here for colors
image = holder.getImage();
/**** This loads the pictures ****/
BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
String imageUrl = imgurl.get(rowData.mId);
Bitmap bm = LoadImage(imageUrl, bmOptions);
image.setImageBitmap(bm);
return convertView;
}
//Load image from the URL
private Bitmap LoadImage(String url, BitmapFactory.Options options) {
Bitmap bitmap = null;
InputStream inStream = null;
try {
inStream = OpenHttpConnection(url);
bitmap = BitmapFactory.decodeStream(inStream, null, options);
inStream.close();
} catch (IOException ioex) {
ioex.printStackTrace();
}
return bitmap;
}
}
/*** Wrapper for row data ***/
private class ViewHolder {
private View mRow;
private TextView title = null;
private TextView detail = null;
private TextView status = null;
private ImageView image = null;
public ViewHolder (View row) {
mRow = row;
}
public TextView getTitle() {
if (title == null) {
title = (TextView) mRow.findViewById(R.id.title);
}
return title;
}
public TextView getDetail() {
if (detail == null) {
detail = (TextView) mRow.findViewById(R.id.detail);
}
return detail;
}
public TextView getStatus() {
if (status == null) {
status = (TextView) mRow.findViewById(R.id.status);
}
return status;
}
public ImageView getImage() {
if (image == null) {
image = (ImageView) mRow.findViewById(R.id.thumbnail);
}
return image;
}
}
}
Thanks a lot for any pointers.
Check out the AsyncTask. This will let you background your long-running processes while showing the UI.
Also, you can find good/official tutorial on Android threading here.
I ended up using standard java Thread to load the data from API in the background and created a separate class for loading images in separate threads as well. In case you're wondering it now looks like this, and seem to work fine.
Loading the data:
public void onCreate(...) {
//...
mHandler = new Handler();
dialog = ProgressDialog.show(VodsActivity.this, "","Loading. Please wait...", true);
getData.start();
}
private Thread getData = new Thread() {
public void run() {
try {
loadData();
mHandler.post(showData);
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
private Runnable showData = new Runnable() {
public void run() {
try {
displayData();
dialog.dismiss();
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
Loading images (in CustomAdapter):
String imageUrl = imgurl.get(rowData.mId);
final ImageView image = holder.getImage();
//Reuse downloaded images or download new in separate thread
image.setTag(imageUrl);
Drawable cachedImage = imageLoader.loadDrawable(imageUrl, new ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag = (ImageView) image.findViewWithTag(imageUrl);
if (imageViewByTag != null) {
imageViewByTag.setImageDrawable(imageDrawable);
}
}
});
image.setImageDrawable(cachedImage);
ImageLoader class:
public class ImageLoader {
private HashMap<String, SoftReference<Drawable>> imageCache;
private static final String TAG = "ImageLoader";
public ImageLoader() {
imageCache = new HashMap<String, SoftReference<Drawable>>();
}
//Loads image from the cache if it exists or launches new thread to download it
public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
Log.d(TAG, "loadDrawable(" + imageUrl + ")");
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
Drawable drawable = softReference.get();
if (drawable != null) {
return drawable;
}
}
final Handler handler = new Handler() {
#Override
public void handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};
new Thread() {
#Override
public void run() {
Drawable drawable = loadImageFromUrl(imageUrl);
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}
}.start();
return null;
}
//Downloads image from the url
public static Drawable loadImageFromUrl(String url) {
Log.d(TAG, "loadImageFromUrl(" + url + ")");
InputStream inputStream;
try {
inputStream = new URL(url).openStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
return Drawable.createFromStream(inputStream, "src");
}
public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}
}