Image caching not in List View android - java

Hi guys i am stuck with image caching. i need to populate Linear Layout with images from web.
I was searching examples how to cache images in android and found these examples:
http://developer.android.com/resources/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.html
Lazy load of images in ListView
I tried it implement for my code.
String picPath = "https://www.google.lt/logos/classicplus.png";
try {
/*
View v = null;//new View(this);
ImageLoader loader = new ImageLoader(this);
ImageView im = (ImageView)this.findViewById(R.id.image);
loader.DisplayImage(picPath, im);
addImage( im);*/
LayoutInflater inflater =(LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = inflater.inflate(R.layout.item, null);
ImageView image = (ImageView)convertView.findViewById(R.id.image);
ImageDownloader down = new ImageDownloader();
down.download(picPath, image);
addImage(image);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
public void addImage( View view){
LinearLayout pubLayout = (LinearLayout)findViewById( R.id.scrollerLinearlayout);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
//setting layout_margin
params.setMargins(15, 30, 15, 30);
pubLayout.addView(view,params);
}
However this didn't worked. I believe because i add view to linear layout and when image is downloaded it can't repaint it ?
There are examples how to do image caching using ListView. But what to do if i am not using List View.
I would write my own caching but how to make callback to image downloaded as i want first add image to layout and on callback update it ?
Thanks.

you have to call invalidate on parent view
pubLayout.getParent().invalidate();

Related

How to display a simple ImageButton on a customly created view?

I've been browsing the entire internet, but I could not find any answer to this question. I want to create a background, some image buttons, along with a bunch of moving graphics (circles). Since I do not know how to overwrite a xml layout with moving graphics, I chose to customly create my view, draw the background, the imageButtons and the circles (2D graphics).
public class GameView extends View implements UtilConstants
since I extended the View class, I had to call the super class constructor in my constructor
GameView(Context context) {
super(context);
this.context = context;
this.paint = new Paint();
}
and to implement the onDraw method, which acts like the java paintComponent
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // necessary for some reason
setGridBackground(); // sets the background
paint.setColor(Color.parseColor("#FF0000"));
canvas.drawCircle(this.x += 10, 300, 20, paint); //moves my graphics (ball) within the screen
drawScoreInLeftUpperCorner(canvas, 20); // paints a string text on the screen
setAbilitiesImages(); // places some imageButtons
try {
Thread.sleep(THREAD_REFRESH_RATE_MS);
} catch (InterruptedException ex) {
System.out.println(ex);
}
invalidate();
}
Now, to get to my problem:
I do not know how to set those ImageButtons !!! I am trying
private void setAbilititesImages() {
ImageButton imageButton = new ImageButton(this.context); // is this ok to put the argument this.context??
imageButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
imageButton.setImageResource(R.drawable.monster); // set my resource
RelativeLayout relativeLayout = findViewById(R.id.in_game_layout); // what is the purpose of this???
if (relativeLayout != null) { // it never enters this if, relativeLayout is always null
relativeLayout.addView(imageButton);
}
}
Aaaaand the image button never shows up...why is it necessary to use Relative/Linear layouts? That R.id.in_game_layout I created is just an empty RelativeLayout xml. Can't I just use something like
imageButton.setImageResource(R.drawable.monster); // set my resource
imageButton.setBounds(.....);
(View)this.add(imageButton); ???
ImageButton requires a parent view to be hosted in it. The parent View can be a RelativeLayout, a linearlayout or a ConstraintLayout.
In your case, the instance relativeLayout is always null because you not specify the view parent in which you do findViewById.
You should make something like :
RelativeLayout relativeLayout = view.findViewById(R.id.in_game_layout);
You need to add layout param to your parent Relative layout also to display your Image button appropriately.
Example
RelativeLayout relativeLayout = findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ImageButton imageButton = new ImageButton(this);
imageButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_background,null));
relativeLayout.addView(imageButton,params);

RelativeLayout addRule at BaseAdapter doesn't work very well

After one of rule is added to RelativeLayout, I get a don't very correct result. ID does not apply to element/is applied incorrectly. This affects at rules that must be bound to widget.
As a container, I use ListView and add objects to it through BaseAdapter. This obviously does not give desired result, but after reusing same widget that is returned back to the adapter and reused (element is guaranteed not changing again), rules starting working correctly.
#Override
protected void onCreate(Bundle state) {
super.onCreate(state);
ListView view = new ListView(this);
view.setBackgroundColor(Color.BLACK);
view.setId("files_list".hashCode());
view.setAdapter(new TestAdapter(this));
...
private class TestAdapter extends BaseAdapter {
...
#Override
public View getView(int position, View convertView, View parent) {
if(convertView == null) convertView = inflateView();
// only changes text & pictures, doesn't affecting display
manipulateItem(position, convertView);
return convertView;
...
private View inflateView() {
RelativeLayout layout = new RelativeLayout(context);
layout.setLayoutParams(new ViewGroup.LayoutParams(-1, -2));
ImageView icon = new ImageView(context);
icon.setBackgroundColor(Color.BLACK);
icon.setPadding(20, 20, 20, 20);
icon.setId("file_icon".hashCode());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(110, -1);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.rightMargin = 30;
layout.addView(icon, params);
...
LinearLayout additional = new LinearLayout(context);
additional.setOrientation(LinearLayout.VERTICAL);
additional.setGravity(Gravity.RIGHT);
additional.setBackgroundColor(Color.RED);
additional.setPadding(30, 0, 30, 0);
additional.setId(java.lang.String("additional_info").hashCode());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, -2);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
layout.addView(additional, params);
...
LinearLayout uniqal = new LinearLayout(context);
uniqal.setOrientation(LinearLayout.VERTICAL);
uniqal.setBackgroundColor(Color.BLUE);
uniqal.setId("uniqal_info".hashCode());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, -2);
// problem occurs here
params.addRule(RelativeLayout.LEFT_OF, additional.getId());
params.addRule(RelativeLayout.RIGHT_OF, icon.getId());
params.addRule(RelativeLayout.CENTER_IN_PARENT);
layout.addView(uniqal, params);
...
return layout;
}
This is what widget will looks like after first scrolling: elements after first drawing screen
And so, after scrolling and reusing same widget: working screen
After firstly 5 uses (so much got into my test screen), everything becomes fine. For the first time, views don't want to be attached by ID to another widget in any way. Is there a way around this?
Options for inflating layout from application .xml don't suit me
Manual update of layout helped me, however this doesn't work right away and my question remains relevant. Here is modified inflateView code:
private View inflateView() {
...
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, -2);
params.addRule(RelativeLayout.LEFT_OF, additional.getId());
params.addRule(RelativeLayout.RIGHT_OF, icon.getId());
params.addRule(RelativeLayout.CENTER_IN_PARENT);
uniqal.post(new Runnable() {
public void run() {
uniqal.requestLayout();
}
});
layout.addView(uniqal, params);
...
return layout;
}

RecylerView Lags when adding Images from Drawable to ArrayList

I am loading images into ArrayList and then setting it to RecylerView with GridLayout. The images are loaded and everything looks good. But when I scroll the RecylerView it starts lagging.Though images are loaded completely there is a lag while scrolling.
Some answers I came across were about lazy loading the images or using Glide or Picasso libraries. But how can I implement it?
Here's how I am adding images.
MainActivity:
int imageArray[] = new int[]{
R.drawable.one,
R.drawable.two, R.drawable.three,
R.drawable.four,R.drawable.five,...
};
private ArrayList prepareData(){
ArrayList arrayList = new ArrayList();
for(int i=0;i<names.length;i++){
MyModel myModel = new MyModel();
myModel.setDrawable(imageArray[i]);
arrayList.add(myModel);
}
return arrayList;
}
Here's my Adapter code:
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.images_card, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.tv_logo.setImageResource(mArrayList.get(i).getDrawable());
}
If you are using Glide then use following code to load your drawable image into imageview using Glide
Glide.with(context).load(R.drawable.yourImage).into(imageView);
Where "context" is your activity context
and "imageView" is your object of ImageView
You can also use the native code of your network calling library that show images, and also if there is a sort of lagging, you can add progress bar in your image view for good user experience and also try to use AppCompatImageView instead of ImageView in your layout.
It's better to use Glide or Picasso for image loading.
Try this
Glide.with(yourContext).load(imageArray[position]).into(viewHolder.tv_logo);
Image loading would be smooth and fast.
You can try Picasso also.
Happy Coding :)

Android: How to add a layer on top no matter how many activities started?

I want to play a gif animation and this view will move on the screen every second, but if I start an activity I need to add this view again and the position will change.
See the attached image below. I need to stick this over every view. Any way to do it?
Create one BaseActivity for all activities in your app to show Overlay View or Layout.
you can inherit BaseActivity on other Activity
You can add gif supported views or layouts
for example i added overlay_layout in my showOverlay method.
you can call showOverlay method where ever you want to show and you can remove with removeOverlay with conditions.
Please note that showOverlay and removeOverlay should be in BaseActivity
void showOverlay(){
LayoutInflater inflater = activity.getLayoutInflater();
layout = inflater.inflate(R.layout.overlay_layout, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.gravity = Gravity.BOTTOM;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.type = WindowManager.LayoutParams.TYPE_APPLICATION;
final WindowManager mWindowManager = (WindowManager);
activity.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(layout, params);
}
void removeOverlay(){
windowManager.removeView(view);
}
set this view into WindowManager and it will always show on top

Create ImageViews dynamically inside a loop

I have written this code that loads an image to in ImageView widget:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gallery);
i = (ImageView)findViewById(R.id.imageView1);
new get_image("https://www.google.com/images/srpr/logo4w.png") {
ImageView imageView1 = new ImageView(GalleryActivity.this);
ProgressDialog dialog = ProgressDialog.show(GalleryActivity.this, "", "Loading. Please wait...", true);
protected void onPreExecute(){
super.onPreExecute();
}
protected void onPostExecute(Boolean result) {
i.setImageBitmap(bitmap);
dialog.dismiss();
}
}.execute();
}
bu now, I want to load several images. for this I need create image views dynamically but i don't know how...
I want run my code inside a for loop:
for(int i;i<range;i++){
//LOAD SEVERAL IMAGES. READ URL FROM AN ARRAY
}
my main problem is creating several ImageViews inside a loop dynamically
you can modify the layout , image resource and no of images (may be dynamic as well) according to your requirement...
LinearLayout layout = (LinearLayout)findViewById(R.id.imageLayout);
for(int i=0;i<10;i++)
{
ImageView image = new ImageView(this);
image.setLayoutParams(new android.view.ViewGroup.LayoutParams(80,60));
image.setMaxHeight(20);
image.setMaxWidth(20);
// Adds the view to the layout
layout.addView(image);
}
You can use this code to create ImageViews
ImageView image = new ImageView(this);
LinearLayout.LayoutParams vp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
image.setLayoutParams(vp);
image.setMaxHeight(50);
image.setMaxWidth(50);
// other image settings
image.setImageDrawable(drawable);
theLayout.addView(image);
where theLayout is the layout you want to add your image views to.
For more customization check out the dev page, where all the possible options are listed.
If your requirement is show in List or Gridview then you should go for Lazy Loading List or grid.
Please go through the below link.
https://github.com/thest1/LazyList
https://github.com/abscondment/lazy-gallery
Try this
rootLayout = (LinearLayout) view1.findViewById(R.id.linearLayout1);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_VERTICAL;
params.setMargins(0, 0, 60, 0);
for(int x=0;x<2;x++) {
ImageView image = new ImageView(getActivity());
image.setBackgroundResource(R.drawable.ic_swimming);
rootLayout.addView(image);
}

Categories

Resources