i am using Universal Image Loader and get data from url.
but i dont know how to get a result of String[] for position.
my code as follow. it show the an mistake"The value of the local variable IMAGES is not used"
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
view = getActivity().getLayoutInflater().inflate(R.layout.fragment_monster_list_item, parent, false);
holder = new ViewHolder();
holder.text = (TextView) view.findViewById(R.id.text);
holder.image = (ImageView) view.findViewById(R.id.image);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.text.setText("this is number "+ (position+1)+"photo" );
imageLoader.displayImage(IMAGES[position], holder.image, options, animateFirstListener);
return view;
}
class showTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("http://garyhui86.er-webs.com/monstersxml.php");
HttpURLConnection urlConn =
(HttpURLConnection)url.openConnection();
if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
DocumentBuilder builder = DocumentBuilderFactory
.newInstance().newDocumentBuilder();
Document document = builder.parse(urlConn.getInputStream());
NodeList nodeList = document.getElementsByTagName("Info");
for (int i = 0; i < nodeList.getLength(); i++) {
NamedNodeMap attributes=nodeList.item(i).getAttributes();
String monstersname=attributes.getNamedItem("monsters_name").getNodeValue();
String monstersimage=attributes.getNamedItem("monsters_image").getNodeValue();
Log.i("ttt", monstersname);
categoryList.add(monstersname);
Monsters_image.add(monstersimage);
}
}
urlConn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
String[] IMAGES = Monsters_image.toArray(new String[Monsters_image.size()]);
}
}
Don't worry about that warning, I would say. It's only telling you IMAGES is never mentioned except where it is declared. I guess your code is not yet complete, otherwise you would not have an unused variable. I bet if you go on writing your code, there will be some point where you will use that variable, and make the warning disappear.
I do not actually understand your code, as try and catch are constructs I have never used or been taught to use, but finishing the program before minding warnings is a good idea. By the way, once you get to the point of using that String[] IMAGES somewhere, save the document, because otherwise the editor might remember the "mistake" and keep warning you.
Related
Please help me out
I am fetching image from a JSON API to my android app for each item in my arraylist. The images are fetching correctly, but instead of setting only the image that is meant for each list item, it is looping and interchanging all the images in all the list on one item and all the list items respectively, thereby making the image in each list item to be changing to different images in seconds.
See the JSON file
{ "data":[
{
"sno":1,
"id":"3",
"title":"This Is Great Again",
"desc":"The details of how a UUID is generated are determined by the device manufacturer and are specific to the device's platform or model.The details of...",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/145277f3d0499ee8e0dafbac384ca9b4.jpg",
"date_added":"2017-10-12 10:26PM",
"no_comment":3,
"comments":[ ]
},
{
"sno":2,
"id":"6",
"title":"Money Makes The World Go Round",
"desc":"On this realm, nothing works without money. You need to get some of it or else you'll be grounded.",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/546a4c29a94f3d70ae9a075ce8afcc6b.jpg",
"date_added":"2018-02-18 10:06AM",
"no_comment":0,
"comments":[ ]
},
{
"sno":3,
"id":"7",
"title":"No One Is Destined To Be Poor",
"desc":"You will not be poor.",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/8f19b9cebd1ca4dec74fafcfe23ae0f0.jpg",
"date_added":"2018-02-18 01:03PM",
"no_comment":0,
"comments":[ ]
},
{
"sno":4,
"id":"8",
"title":"What Is Your Money?",
"desc":"Understand the true definition of your money.",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/49b35ffb5cabcb7e01dab2d452ec6025.jpg",
"date_added":"2018-02-18 01:30PM",
"no_comment":0,
"comments":[ ]
},
Here is my code for fetching each item and the image
private static ArrayList<nauget> extractFeatureFromJson(String freeNaugetJson) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(freeNaugetJson)) {
return null;
}
ArrayList<nauget> naugets = new ArrayList<nauget>();
try {
JSONObject baseJsonResponse = new JSONObject(freeNaugetJson);
JSONArray dataArray = baseJsonResponse.getJSONArray("data");
// If there are results in the data array
for (int i = 0; i < dataArray.length(); i++){
String title = dataArray.getJSONObject(i).getString("title");
String body = dataArray.getJSONObject(i).getString("desc");
String totalComments = dataArray.getJSONObject(i).getString("no_comment");
String image = dataArray.getJSONObject(i).getString("image");
int id = dataArray.getJSONObject(i).getInt("id");
ArrayList<Comment> comments = new ArrayList<Comment>();
//fetch each comment detail
if (Integer.parseInt(totalComments) > 0) {
JSONArray commentArray = dataArray.getJSONObject(i).getJSONArray("comments");
for (int j = 0; j < commentArray.length(); j++) {
String userName = commentArray.getJSONObject(j).getString("userName");
String comment_image = commentArray.getJSONObject(j).getString("userPhoto");
String comment = commentArray.getJSONObject(j).getString("comment");
String date = commentArray.getJSONObject(j).getString("date_commented");
comments.add(new Comment(userName, comment_image, comment, date));
}
}
// Create a new nauget object
naugets.add(new nauget(title, body, image, totalComments, comments, id));
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the nauget JSON results", e);
}
return naugets;
}
Here is my custom adapter code where am setting the image and its text data for each list item.
public class NaugetAddapter extends ArrayAdapter<nauget> {
ArrayList<nauget> naugets;
private nauget currentNauget;
private ImageView naugetImage;
private TextView naugetTitle;
private TextView naugetBody;
private TextView commentCount;
public NaugetAddapter(#NonNull Context context, ArrayList<nauget> naugets) {
super(context, 0, naugets);
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//check if the convert view is null and inflate the view
if (convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.free_nauget_item, parent, false);
}
currentNauget = (nauget) getItem(position);
//find the nauget title textView and set the text
naugetTitle = (TextView) convertView.findViewById(R.id.nauget_title);
naugetTitle.setText(currentNauget.getNauget_title());
//find the nauget body textView and set the text
naugetBody = (TextView) convertView.findViewById(R.id.nauget_body);
naugetBody.setText(currentNauget.getNauget_body());
//set the nauget total comment count
commentCount = (TextView) convertView.findViewById(R.id.comment_count);
commentCount.setText(currentNauget.getNaugetTotalComments());
//set the comment text
TextView commentText = (TextView) convertView.findViewById(R.id.comment_text);
commentText.setText(currentNauget.getNaugetCommentText());
//set the nauget image
naugetImage = (ImageView) convertView.findViewById(R.id.nauget_image);
new DownloadImageTask().execute(currentNauget.getImageUrl());
//set the share icon
ImageView shareIcon = (ImageView) convertView.findViewById(R.id.share_icon);
shareIcon.setImageResource(currentNauget.getNaugetShareIcon());
//set share functionality on the share icon
shareIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "My App");
shareIntent.putExtra(Intent.EXTRA_TEXT,
naugetTitle.getText()
+ "\n" + naugetBody.getText()
+ "\n" + naugetImage.getDrawable());
startActivity(getContext(), Intent.createChooser(shareIntent, "Share via"), null);
}
});
return convertView;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// mLoadingIndicator.setVisibility(View.VISIBLE);
}
protected Bitmap doInBackground(String... urls) {
Bitmap image = null;
HttpURLConnection urlConnection = null;
try {URL url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode != 200) {
return null;
}
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (Exception e) {
urlConnection.disconnect();
Log.e("Error", e.getMessage());
e.printStackTrace();
}finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
protected void onPostExecute(Bitmap result) {
// mLoadingIndicator.setVisibility(View.INVISIBLE);
naugetImage.setImageBitmap(result);
}
}
#NonNull
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<nauget> filteredResults = new ArrayList<>();
FilterResults results = new FilterResults();
results.values = filteredResults;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
}
};
}
void setFilter(ArrayList<nauget> listItem){
naugets = new ArrayList();
naugets.addAll(listItem);
notifyDataSetChanged();
}
}
This should solve the issue! you are trying everything fine but you have the comment ArrayList inside of a loop getting instantiated each time newly just put it before the outer loop as I did here and the error should go! TRY IT
try {
JSONObject baseJsonResponse = new JSONObject(freeNaugetJson);
JSONArray dataArray = baseJsonResponse.getJSONArray("data");
//put it here so you won't get a new array for each comment in the loop
**ArrayList<Comment> comments = new ArrayList<Comment>();**
// If there are results in the data array
for (int i = 0; i < dataArray.length(); i++){
String title = dataArray.getJSONObject(i).getString("title");
String body = dataArray.getJSONObject(i).getString("desc");
String totalComments = dataArray.getJSONObject(i).getString("no_comment");
String image = dataArray.getJSONObject(i).getString("image");
int id = dataArray.getJSONObject(i).getInt("id");
//here after every comment check its making a new comment ArrayList for each comment and filling it out so this can be the cause of the bug! bcz its in the loop
// ArrayList<Comment> comments = new ArrayList<Comment>();
//fetch each comment detail
if (Integer.parseInt(totalComments) > 0) {
JSONArray commentArray = dataArray.getJSONObject(i).getJSONArray("comments");
for (int j = 0; j < commentArray.length(); j++) {
String userName = commentArray.getJSONObject(j).getString("userName");
String comment_image = commentArray.getJSONObject(j).getString("userPhoto");
String comment = commentArray.getJSONObject(j).getString("comment");
String date = commentArray.getJSONObject(j).getString("date_commented");
comments.add(new Comment(userName, comment_image, comment, date));
}
}
// Create a new nauget object
naugets.add(new nauget(title, body, image, totalComments, comments, id));
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the nauget JSON results", e);
}
return naugets;
I have been searching SO threads for answers but couldn't figure out my issue from previous discussion. I have a listview which loads about 50 images (it used to be about 100 but this was barely loading any images at all). After grabbing my JSON content (including image URL) from an api endpoint, through an adapter, my code puts it inside the listview.
Currently, with 50 images, picasso will load one image at a time as I scroll down on the feed. I feel as if keeping the scroll fixed on one item in the listview will make that image load faster. As I scroll up, however, it puts the placeholder back in and reloads the image again. Is there a way to solve this issue?
public class MainActivity extends Activity {
private List<Post> myPosts = new ArrayList<Post>();
protected String[] mBlogPostTitles;
public static final String TAG = MainActivity.class.getSimpleName();//prints name of class without package name
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(isNetworkAvailable()) {
GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask(); // new thread
getBlogPostsTask.execute();// don't call do in background directly
}else{
Toast.makeText(this, "Network is unavailable", Toast.LENGTH_LONG).show();
}
}
public boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if(networkInfo != null && networkInfo.isConnected()){
isAvailable = true;
}
return isAvailable;
}
private void populateListView() {
ArrayAdapter<Post> adapter = new MyListAdapter();
ListView list = (ListView) findViewById(R.id.postsListView);
list.setAdapter(adapter);
}
private class MyListAdapter extends ArrayAdapter<Post>{
public MyListAdapter() {
super(MainActivity.this, R.layout.item_view, myPosts);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// make sure we have a view to work with
View itemView = convertView;
if (itemView == null) {
itemView = getLayoutInflater().inflate(R.layout.item_view, parent,false);
}
//find the post to work with
Post currentPost = myPosts.get(position);
Context context = itemView.getContext();
String imageURL = currentPost.getImage();
if(imageURL == null || imageURL.isEmpty()){
ImageView imageView = (ImageView) itemView.findViewById(R.id.item_image);
imageView.setVisibility(View.GONE);
}else{
ImageView imageView = (ImageView) itemView.findViewById(R.id.item_image);
Picasso.with(context)
.load(imageURL)
.tag(context)
.placeholder(R.drawable.kanye8080s)
.error(R.drawable.stadiumarcadium)
.into(imageView);
imageView.setVisibility(View.VISIBLE);
}
//Username
TextView userText = (TextView) itemView.findViewById(R.id.item_txtUser);
userText.setText(currentPost.getUser());
//Time of post
TextView timeText = (TextView) itemView.findViewById(R.id.item_txtTime);
timeText.setText("" + currentPost.getTime());
//The actual post
TextView postText = (TextView) itemView.findViewById(R.id.item_txtPost);
postText.setText("" + currentPost.getPost());
//The actual post
TextView likesText = (TextView) itemView.findViewById(R.id.item_txtLikes);
likesText.setText("" + currentPost.getLikes());
return itemView;
}
}
private class GetBlogPostsTask extends AsyncTask<Object, Void, List> {
#Override
protected List doInBackground(Object[] params) {
int responseCode = -1;//need to have this variable outside scope of try/catch block
JSONObject jsonResponse = null;
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(""); /// api endpoint redacted
try {
HttpResponse response = client.execute(httpget);
StatusLine statusLine = response.getStatusLine();
responseCode = statusLine.getStatusCode();
if(responseCode == HttpURLConnection.HTTP_OK){ //could have used just 200 value
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while((line = reader.readLine()) != null){
builder.append(line);
}
jsonResponse = new JSONObject(builder.toString());
JSONArray jsonPosts = jsonResponse.getJSONArray("posts");
for(int i=0; i < jsonPosts.length(); i++ ){
JSONObject jsonPost = jsonPosts.getJSONObject(i);
int post_id = Integer.parseInt(jsonPost.getString("id"));
String post_user = jsonPost.getString("user");
String post_account = jsonPost.getString("account");
int post_time = Integer.parseInt(jsonPost.getString("time"));
String post_post = jsonPost.getString("post");
String post_image = jsonPost.getString("image");
int post_likes = Integer.parseInt(jsonPost.getString("likes"));
myPosts.add(new Post(post_id, post_user, post_account, post_time, post_post, post_image, "profile picture here", post_likes));
}
}else{
Log.i(TAG, "Unsuccessful HTTP Response Code: " + responseCode);
}
}
catch (MalformedURLException e){
Log.e(TAG, "Exception caught");
}
catch (IOException e){
Log.e(TAG, "Exception caught");
}
catch (Exception e){//must be in this order, this is the last, general catch
Log.e(TAG, "Exception caught", e);
}
return null;
}
#Override
protected void onPostExecute(List result) {
// call populateListView method here
populateListView();
super.onPostExecute(result);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
EDIT:
I have updated my code into a view holder pattern, created two separate views (one for a post with an image, one for a post with just text) and also included Picasso's new scroll detection capabilities.
I have seen an improvement in some of the images loading quicker, at least when the view is focused while scrolling, the image is more likely to load now. However, on scroll up those same images that were once loaded, disappear. It feels as if Picasso is only loading 4-5 images at a time and replacing the ones already loaded to make room. My updated code is below:
public class MainActivity extends Activity {
private List<Post> myPosts = new ArrayList<Post>();
protected String[] mBlogPostTitles;
public static final String TAG = MainActivity.class.getSimpleName();//prints name of class without package name
...
private void populateListView() {
Activity activity = MainActivity.this;
ArrayAdapter<Post> adapter = new MyListAdapter();
ListView list = (ListView) findViewById(R.id.postsListView);
list.setAdapter(adapter);
list.setOnScrollListener(new SampleScrollListener(activity));
}
private class MyListAdapter extends ArrayAdapter<Post>{
public MyListAdapter() {
super(MainActivity.this, R.layout.item_view, myPosts);
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
String imageURL = myPosts.get(position).getImage();
if(imageURL == null || imageURL.isEmpty()){
return 1; // text based
}else{
return 0; // image based
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
PostViewHolder holder;
int type = getItemViewType(position);
View itemView = convertView;
// make sure we have a view to work with
if (itemView == null) {
holder = new PostViewHolder();
if(type == 1) {
itemView = getLayoutInflater().inflate(R.layout.item_view, parent, false);
} else {
itemView = getLayoutInflater().inflate(R.layout.image_post_view, parent, false);
holder.image = (ImageView) itemView.findViewById(R.id.item_image);
}
holder.user = (TextView) itemView.findViewById(R.id.item_txtUser);
holder.time = (TextView) itemView.findViewById(R.id.item_txtTime);
holder.post = (TextView) itemView.findViewById(R.id.item_txtPost);
holder.likes = (TextView) itemView.findViewById(R.id.item_txtLikes);
itemView.setTag(holder);
} else {
holder = (PostViewHolder) itemView.getTag();
}
//find the post to work with
Post currentPost = myPosts.get(position);
if(type != 1) {
Context context = itemView.getContext();
String imageURL = currentPost.getImage();
Picasso.with(context).setIndicatorsEnabled(true);
//Picasso.with(context).setLoggingEnabled(true);
Picasso.with(context)
.load(imageURL)
.tag(context)
.placeholder(R.drawable.kanye8080s)
//.skipMemoryCache()
.error(R.drawable.stadiumarcadium)
.fit()
.into(holder.image);
}
//Username
holder.user.setText(currentPost.getUser());
//Time of post
holder.time.setText("" + currentPost.getTime());
//The actual post
holder.post.setText(currentPost.getPost());
//Likes for the post
holder.likes.setText("" + currentPost.getLikes());
return itemView;
}
}
public class SampleScrollListener implements AbsListView.OnScrollListener {
private final Context context;
public SampleScrollListener(Context context) {
this.context = context;
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
final Picasso picasso = Picasso.with(context);
if (scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL) {
picasso.resumeTag(context);
} else {
picasso.pauseTag(context);
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
// Do nothing.
}
}
...
}
Where is the issue coming from? Should I be preloading these images somehow in the cache? While I have already looked into Picasso's new priority feature, should I be telling Picasso somehow to load images in the order in which they appear in my listview? Any ideas? How can I "keep" images that have already been loaded on scroll up?
use resize with picasso
Picasso.with(context)
.load(imageURL)
.tag(context)
.placeholder(R.drawable.kanye8080s)
.error(R.drawable.stadiumarcadium)
.into(imageView)
.resize(x,y);
//This would definitely help
The size of the memory cache of Picasso is limited so it does not generate out of memory errors when scrolling long lists. Once the images are out of the memory cache, the placeholder will be displayed while the image is reloaded from either the disk cache or the network.
The disk cache is enabled by default so the reload time should be very fast. You can use setIndicatorsEnabled(true) to see where the images are being loaded from.
If you are finding that Picasso is reloading the images from network, this is probably a problem with the HTTP headers being sent from the server. I don't believe Picasso actually caches the images on disk itself, instead relying on the HTTP layer, which will obey a no-cache header, and will reload from network if the expire time elapses.
I'd look at two things.
Number one is the sizes of the images being loaded. I don't know what the default maximum cache size is in Picasso, but it sounds like you may be exceeding it with just a few images, causing the others to be evicted from the cache.
Number two is probably not the core issue, but also contributes to performance.
You are doing a lot findViewById() calls, which are fairly expensive.
Look into the "ViewHolder" pattern for "caching" those lookups.
Edit - see Jake Wharton's answer to a similar question for more detail
Use :
recyclerview.getRecycledViewPool().setMaxRecycledViews(0, 0);
This solved my issue
I would suggest you to use GLIDE for image loading. Since GLIDE is fast and with its cache loading feature you can get super fast image loading, With GLIDE you get lot of features..
Download here
https://github.com/bumptech/glide
hi i have a gridview (It has two textboxes and one imageview)
The items are populated from db. I use a standard photo for items that haven't a photo. App works with 50 items but with 200 items it gives some error.
logcat** java.lang.OutOfMemoryError at
android.graphics.BitmapFactory.nativeDecodeStream(Native Method) at
android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:652)
ı try some methods that get from google suggest for loading large bitmap, but it didnt work. http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
when I set inJustDecodeBounds true, app works but all items come empty..
here is my code get info from db:
private void refreshList(String sql)
{
gridArray = new ArrayList<Stock>();
final Cursor cursor = _SQLite.RawQueryTry(sql, null);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
if (cursor != null)
{
if (cursor.moveToFirst())
{
for (int i = 0; i < cursor.getCount(); i++)
{
byte[] blob = cursor.getBlob(cursor.getColumnIndex("FOTO"));
Bitmap stockImage = null;
ByteArrayInputStream inputStream = null;
if (blob == null)
{
options.inJustDecodeBounds=false;
stockImage = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.foto_yok, options);
}
else
{
inputStream = new ByteArrayInputStream(blob);
stockImage = BitmapFactory.decodeStream(inputStream, null, options);
}
String stockName = cursor.getString(cursor.getColumnIndex("STOK_ADI"));
String stockNo = cursor.getString(cursor.getColumnIndex("STOK_NO"));
String stockCode = cursor.getString(cursor.getColumnIndex("STOK_KODU"));
String stockEntity = cursor.getString(cursor.getColumnIndex("BIRIM"));
String stockKdvOranı = cursor.getString(cursor.getColumnIndex("KDV_ORANI"));
String stockRatio = TableUtils.getFieldValue("KATSAYI", "BIRIM", stockEntity, "STOKBIRI");
String stockAmount = cursor.getString(cursor.getColumnIndex("MIKTAR"));
gridArray.add(new Stock(stockImage, stockName, stockNo, stockCode, stockKdvOranı, stockEntity, stockAmount, stockRatio, processNo));
cursor.moveToNext();
}
}
}
gridAdapter = new AdapterStockGridView(this, R.layout.stockgriditems, gridArray);
gridView.setAdapter(gridAdapter);
}
and my adapter class :
public class AdapterStockGridView extends ArrayAdapter<Stock>
{
Context context;
int id;
ArrayList<Stock> stock = new ArrayList<Stock>();
public AdapterStockGridView(Context context, int id, ArrayList<Stock> stock)
{
super(context, id, stock);
this.id = id;
this.context = context;
this.stock = stock;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
RecordHolder holder = null;
if (row == null)
{
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(id, parent, false);
holder = new RecordHolder();
holder.stockCode = (TextView) row.findViewById(R.id.stockCode);
holder.stockName = (TextView) row.findViewById(R.id.stockName);
holder.stockImage = (ImageView) row.findViewById(R.id.stockImage);
row.setTag(holder);
}
else
{
holder = (RecordHolder) row.getTag();
}
Stock item = stock.get(position);
holder.stockCode.setText(item.getStockCode());
holder.stockName.setText(item.getStockName());
holder.stockImage.setImageBitmap(item.getStockImage());
return row;
}
}
static class RecordHolder
{
TextView stockName;
TextView stockCode;
ImageView stockImage;
}
}
Maybe you're storing the blob as full size? If so, there's no need to do that as you're wasting too much space and you're having these memory issues. The users is not going to see the big image anyway, so redo your image storing in order to store the scaled down images as blobs.
You're getting these OOE because you're loading the full blob byte array - and the way it is now, you can't make use of the article from developer article.
Also, don't load the images in that Stock object as you're going to hold them unnecessarily. Rather than that, use a bitmap loader mechanism that keeps the images in a LRUCache and if not found in there, it loads them from database. In your GridView adapter getView method request to load that image. If found in LRUCache, get it from there, if not start an AsyncTask to get it from DB, add it in LRUCache and display it to the user.
Here is a link with caching bitmaps with LRUCache.
I want to read images from URL and show it in android gallery widget.
so I wrote below code in onCreate() method .
list = GuideDAO.getAllImages(businessId);
Gallery g = (Gallery) findViewById(R.id.gallery);
g.setSpacing(2);
// Set the adapter to our custom adapter (below)
if(list.size() > 0)
{
g.setAdapter(new ImageAdapter(this,list));
}
This is my ImageAdapter
public class ImageAdapter extends BaseAdapter {
List<Images> glist = null;
private String url;
public ImageAdapter(Context c,List<Images> lst) {
mContext = c;
glist = lst;
int i=0;
for (Images id : glist) {
url = id.getImageURL(); // Getting URL
InputStream inStream = null;
if (url.startsWith("http")) {
url = url.replace(" ", "%20");
HttpURLConnection conn;
try {
conn = (HttpURLConnection)new URL(url).openConnection();
conn.setDoInput(true);
conn.connect();
inStream = conn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
try {
inStream = new FileInputStream(url);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inPurgeable = true;
Bitmap b = BitmapFactory.decodeStream(inStream, null, options);
mImageCollection[i]=b;
i++;
}
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageBitmap(mImageCollection[position]);
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(136, 88));
return i;
}
private Context mContext;
private String[] mImageURLs = {};
private Bitmap[] mImageCollection = {};
}
This throw error because it not in Thread. How can I change this code so that URL reading and image loads in background?
So I have changed my ImageAdapter by using SmartImageView , which handles background thread and caching.
public class ImageAdapter extends BaseAdapter {
List<ImageGallery> glist = null;
private String url;
public ImageAdapter(Context c,List<ImageGallery> lst) {
mContext = c;
glist = lst;
int i=0;
al = new ArrayList<String>();
for (ImageGallery id : glist) {
al.add(id.getImageURL());
}
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
Log.d("deepak", "getview gallery");
SmartImageView i = new SmartImageView(mContext);
i.setImageUrl(al.get(position));
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(136, 88));
return i;
}
private Context mContext;
private String[] mImageURLs = {};
private ArrayList<String> al;
private Bitmap[] mImageCollection = {};
private Integer[] mImageIds = {};
}
But my getView() is not getting called now.
you can make use of Smart Image view. SmartImageView is a drop-in replacement for Android’s standard ImageView which additionally allows images to be loaded from URLs or the user’s contact address book. Images are cached to memory and to disk for super fast loading.
Please refer the following link for more info https://github.com/loopj/android-smart-image-view .hope this may help u to accomplish ur task
I'd suggest writing an AsyncImageLoader class and having it handle image downloads from http. This way you can cache and manage everything on separate threads and have it set the image to the view once the loading is complete. Also you could use this class throughout the application if you want to download images elsewhere.
you could call something like mImageLoader.loadImage(myImageView, Url) in your adapter and it would drop it in once it was finished loading.
if you want more details let me know :)
Hi my problem is simple : imageviews are not fixed. I saw an answer in this link : link and i do understand the answer but i can't do it. So my question is : How do i turn off view recycling in my Adapter ?
If you want i can put a little bit of code :
public class PortfolioAdapter extends ArrayAdapter<PortfolioView>{
private ArrayList<PortfolioView> items;
public PortfolioAdapter(Context context, int textViewResourceId, ArrayList<PortfolioView> items) {
super(context, textViewResourceId, items);
this.items = items;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.portfolio_rows, null);
}
PortfolioView pv = items.get(position);
if (pv != null) {
TextView ticker = (TextView) v.findViewById(R.id.portfolio_rows_ticker);
TextView location = (TextView)v.findViewById(R.id.portfolio_rows_location);
TextView country = (TextView)v.findViewById(R.id.portfolio_rows_country);
TextView portfolio_value = (TextView)v.findViewById(R.id.portfolio_rows_portfolio_value);
TextView yesterday_earnings = (TextView)v.findViewById(R.id.portfolio_rows_yesterday_earnings);
TextView shares = (TextView)v.findViewById(R.id.portfolio_rows_shares);
TextView last_buy_shares = (TextView)v.findViewById(R.id.portfolio_rows_last_buy_shares);
TextView last_buy = (TextView)v.findViewById(R.id.portfolio_rows_last_buy);
TextView your_shares_held = (TextView)v.findViewById(R.id.portfolio_rows_your_shares_held);
ImageView SmPortrait = (ImageView)v.findViewById(R.id.portfolio_rows_sm_portrait);
if (ticker != null) {
ticker.setText(pv.getPortfolio_ticker());
}
if (location != null) {
location.setText(pv.getLocation());
}
if (country != null) {
country.setText(pv.getCountry());
}
if (portfolio_value != null) {
DecimalFormat f_portfolio_value = new DecimalFormat();
f_portfolio_value.setMaximumFractionDigits(2);
String portfolio_value_format = f_portfolio_value.format(pv.getPortfolio_value());
portfolio_value.setText(portfolio_value_format);
}
if (yesterday_earnings != null) {
DecimalFormat f_yesterday_earnings = new DecimalFormat();
f_yesterday_earnings.setMaximumFractionDigits(2);
String yesterday_earnings_format = f_yesterday_earnings.format(pv.getYesterday_earnings());
yesterday_earnings.setText(yesterday_earnings_format);
}
if (shares != null) {
shares.setText(Integer.toString(pv.getShares()));
}
if (last_buy_shares != null) {
last_buy_shares.setText(Integer.toString(pv.getLast_buy_shares()));
}
if (last_buy != null) {
last_buy.setText(pv.getLast_buy());
}
if (your_shares_held != null) {
your_shares_held.setText(Integer.toString(pv.getYour_shares_held()));
}
if(SmPortrait != null){
createimage(SmPortrait, pv.getSm_portrait());
}
}
return v;
}
private class CreateImage extends AsyncTask<String, Void, Drawable> {
ImageView image;
public CreateImage(ImageView img) {
image = img;
image.invalidate();
}
protected void onPreExecute() {
}
protected Drawable doInBackground(String... urls) {
InputStream is;
Drawable d = null ;
try {
is = (InputStream)new URL(urls[0]).getContent();
d = Drawable.createFromStream(is, "Image");
return d;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return d;
}
protected void onPostExecute(Drawable d) {
image.setBackgroundDrawable(d);
image.invalidateDrawable(d);
}
}
// Catch portrait
public void createimage(ImageView img, String url){
new CreateImage(img).execute(url);
}
}
The basic idea is that when you setup your view you want to add a thumbnail as a placeholder. Then use the Tag property to "mark" the view with something like the ID from the database - this can then be used to identify which row should be getting the image and you shouldn't suffer from shifting rows anymore.
Take a look at the answer to this question by Fedor: link - it provides you with a very good example.
You do not need to invalidate the image drawable after set its background. Remove
image.invalidateDrawable(d);
line from the onPostExecute() method and see if it fixes.
What's it for the method invalidateDrawable about Class ImageView?
I 've found the source core as bellow:
#Override
public void invalidateDrawable(Drawable dr) {
if (dr == mDrawable) {
/* we invalidate the whole view in this case because it's very
* hard to know where the drawable actually is. This is made
* complicated because of the offsets and transformations that
* can be applied. In theory we could get the drawable's bounds
* and run them through the transformation and offsets, but this
* is probably not worth the effort.
*/
invalidate();
} else {
super.invalidateDrawable(dr);
}
}