UI Block on creating imageview at runtime - android

I want to create 600 imageview at runtime and add it to linear layout at runtime.It cause block my user interface. My activity appear when all imageview created and added to linear layout. How to resolve this.
Please help for this.
for(int index = 0; index < ProductItemArray.Image_URL.length; index++)
{
ImageView bottomImageView = new ImageView(context);
bottomImageView.setTag(index);
if(Helper.isTablet(context))
bottomImageView.setLayoutParams(new Gallery.LayoutParams(VirtualMirrorActivity.convertDpToPixel(100, context), VirtualMirrorActivity.convertDpToPixel(100, context)));
else
bottomImageView.setLayoutParams(new Gallery.LayoutParams(VirtualMirrorActivity.convertDpToPixel(80, context), VirtualMirrorActivity.convertDpToPixel(80, context)));
UrlImageViewHelper.setUrlDrawable(bottomImageView, ProductItemArray.Image_URL[index]);
bottomImageView.setBackgroundResource(R.layout.border);
linearLayout3.addView(bottomImageView);
bottomImageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final int position = (Integer) v.getTag();
linearLayout.removeAllViews();
Thread newThread = new Thread(new Runnable() {
public void run() {
isAlreadyExistInWishlist = true;
URL url_1 = null;
try {
VMProductListPaging.productUrl = ProductItemArray.Image_small_URL[position];
VMProductListPaging.productId = ProductItemArray.productId[position];
VMProductListPaging.productName = ProductItemArray.product_Name[position];
url_1 = new URL(ProductItemArray.Image_small_URL[position]);
bmp = BitmapFactory.decodeStream(url_1.openConnection().getInputStream());
isExecuted = true;
bitmapModelsHandler.sendMessage(bitmapModelsHandler.obtainMessage());
}
catch (Exception e) {
//Toast.makeText(context,"Sorry!! This link appears to be broken",Toast.LENGTH_LONG).show();
}
}
});
newThread.start();
}
});
}

Having 600 images in memory in the same time is probably not a good idea.
You should consider using some lazy loading via an adapter (with a ListView, a Gallery, a GridView, a Spinner,etc...) which will manage recycling/releasing of views.

Related

How to update linearlayout child view programmatically in android?

I have created linearylayout programatically. where it has multiple rows created having white background. Now if I click on any row then only that row's imageview icon should be changed(should be green) and other row's imageview background should be changed to white. Is there any substitude of notifyDataSetChanged for linearlayout in android. below is my code.
for (int i = 0; i <= obj_tribe_info.al_ethnicity_secondary.size(); i++) {
final int position = i;
al_eth_bool.add(false);
final LinearLayout ll_values = new LinearLayout(_activity);
ll_values.setOrientation(LinearLayout.HORIZONTAL);
ll_values.setGravity(Gravity.CENTER_VERTICAL);
LayoutParams LLParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
ll_values.setLayoutParams(LLParams);
ll_values.setBackgroundResource(R.drawable.my_tribe_box_top);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(50, 0, 0, 0);
final ImageView iv_icon = new ImageView(_activity);
if (al_eth_bool.get(position)) {
iv_icon.setBackgroundResource(R.drawable.notify_onn);
} else {
iv_icon.setBackgroundResource(R.drawable.notify_off);
}
iv_icon.setLayoutParams(layoutParams);
ll_values.addView(iv_icon);
TextView tv_value = new TextView(_activity);
tv_value.setTextColor(_activity.getResources().getColor(
R.color.black));
tv_value.setLayoutParams(layoutParams);
if (i == 0) {
tv_value.setText(obj_tribe_info.str_ethnicity_primary);
} else {
tv_value.setText(obj_tribe_info.al_ethnicity_secondary
.get(i - 1).str_ethnicity_secondary);
}
ll_values.addView(tv_value);
ll_ethnicity.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
ll_ethnicity.addView(ll_values);
}
});
ll_values.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (al_eth_bool.get(position)) {
iv_icon.setBackgroundResource(R.drawable.notify_off);
al_eth_bool.set(position, false);
} else {
iv_icon.setBackgroundResource(R.drawable.notify_onn);
al_eth_bool.set(position, true);
}
}
});
}
No, there is no substitute for notifyDataSetChanged(), you have to manually inform your ImageViews of that change.
You could iterate like this, as soon as you have a change:
for(int i= 0; i < ll_ethnicity.getChildCount(); i++){
ImageView iv = (ImageView) ((ViewGroup)ll_ethnicity.getChildAt(i)).getChildAt(0);
// new background because something has changed
// check if it's not the imageView you just clicked because you don't want to change its background
iv.setBackground(...);
}
For better performance you may also create an HashMap with your ImageViews and later access it to change some of them as you see fit.
I believe what you're looking for is View.invalidate() method. It tells the application that this view is no longer correct, and it will be redrawn when possible. Call this at the end of the onClick method.

Use Image Gallery as a menu

I'm trying to use an image gallery for my application menu. The objective is that when the user click on a image it will send you to a particular activity. The problem is that I donĀ“t know how to associate each image with each activity. For example if you click on the first image it opens a game, if you click on the second one you go to the application options... How can I do it?
public class Carrusel extends Activity implements OnClickListener {
ImageView lastClicked = null;
int padding = 10;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start);
LinearLayout l;
l = (LinearLayout) findViewById(R.id.carrusel);
int[] images = new int[] { R.drawable.image1, R.drawable.image2,
R.drawable.image3,R.drawable.image4,R.drawable.image5};
for (int i = 0; i <5; i++) {
ImageView iv = new ImageView(this);
iv.setImageResource(images[i]);
iv.setPadding(padding, padding, padding, padding);
iv.setOnClickListener(this);
l.addView(iv);
}
}
#Override
public void onClick(View v) {
Intent i= new Intent (this, Flip3d.class);
startActivity (i);
}
}
The last "onClick" was a test of what I was trying. Obviously in this case all the images open the same activity, that is what I want to change.
Create on OnClickListener for each of your ImageViews.
iv.setOnClickListener (new OnClickListener() {
#Override
OnClick(View v) {
// start the activity you want
}
});
You can set ids for your imageview which can be used in onClick to identify your view.
protected void onCreate(Bundle savedInstanceState) {
// ...
for (int i = 0; i <5; i++) {
ImageView iv = new ImageView(this);
iv.setImageResource(images[i]);
iv.setPadding(padding, padding, padding, padding);
iv.setOnClickListener(this);
iv.setId(mIvIds[i]);
l.addView(iv);
}
}
public void onClick(View v) {
if (v.getId() == mIvIds[0]) {
Intent i= new Intent (this, Flip3d.class);
startActivity (i);
} else if (v.getId() == mIvIds[1]) {
// other stuff
} else if (v.getId() == mIvIds[2]) {
// ...
}
}
But firstly you need to generate new ids for mIvIds[]. In API17 was View.generateViewId() added for this feature. But if only your imageviews are attached to that onclick listener i think there should be no problem if you use some random integers (e.g. 1,2,3,... )

Bring to front part of layout in android

I have a problem with parts of layout. I am adding buttons programmatically, because I want do something like breadcrump. I my solution work good. If I am in first activity I show one button. If I go to second I show two buttons.
This is code:
public class TabsGenerator extends LinearLayout{
public TabsGenerator(Context context) {
super(context);
}
public View addNewLinearLayout(Context context, ArrayList<String> descriptions) {
final HorizontalScrollView horizontalView = new HorizontalScrollView(context);
LinearLayout linearLayout = new LinearLayout(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.height = 60;
linearLayout.setLayoutParams(params);
horizontalView.setLayoutParams(params);
postDelayed(new Runnable() {
public void run() {
horizontalView.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
}
}, 100L);
linearLayout.setGravity(Gravity.TOP);
List<View> components = getButtons(context, descriptions);
for(View component : components) {
linearLayout.addView(component);
}
horizontalView.addView(linearLayout);
return horizontalView;
}
public List<View> getButtons(Context context, ArrayList<String> descriptions) {
List<View> buttons = new ArrayList<View>();
for(int i = 0; i < descriptions.size(); i++) {
buttons.add(createButton(context,i, descriptions));
}
return buttons;
}
public View createButton(final Context context, final int i, final ArrayList<String> descriptions){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.leftMargin = -20;
final Button button = new Button(context);
button.setText(SecondActivity.descriptions.get(i));
button.setBackgroundDrawable(getResources().getDrawable(R.drawable.paseknawigacji));
button.setHorizontallyScrolling(true);
button.setEllipsize(TruncateAt.END);
button.setSingleLine();
button.setWidth(20);
if(i==1)
button.bringToFront();
button.setLayoutParams(params);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ActivityManager am = (ActivityManager) context.
getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();
String className = am.getRunningTasks(1).get(0).topActivity.getClassName();
final String StringClassname = packageName+"."+descriptions.get(i);
Class<?> c = null;
if(StringClassname != null) {
try {
c = Class.forName(StringClassname );
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Intent intent = new Intent();
intent.setClassName(context,StringClassname);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if(!(StringClassname.contains(className))){
for(int j = 0; j<descriptions.size()-1;j++)
if(i<descriptions.size()-1)
descriptions.remove(i+1);
context.startActivity(intent);
}
}
});
return button;
}
}
I have a problem because buttons was added to layout but every buttons has ending by triangular shape. When I add second button he cover this shape.
This is how it is looks:
I want to bring to front ending every button. How I can do that?
Edit: Maybe is other way to create breadcrup in android?
Try to add buttons in the reverse order
Your code
List<View> components = getButtons(context, descriptions);
for(View component : components) {
linearLayout.addView(component);
}
now in reverse order
List<View> components = getButtons(context, descriptions);
for(int i = components.size() - 1; i >= 0; i --) {
View component = components.get (i);
linearLayout.addView(component);
}
(code not compiled, may have errors)
try this
thirdButton.bringtoFront();
SecondButton.bringToFront();
Your will see the triangular shape of third and second button.
Hope so this will work
I dont think yours will work with a linear layout as I have noticed that when using bring to front in a linear layout you automatically set it at the total end (eg its not longer button 1 button 2 button 3 but button 1 button 3 button 2). You would need to use a Relative layout or something similar. This might add a little logic to your code but it should be ok otherwise.
Maybe you can try setting elevation in your buttons
But I think the leftMargin= -20 is the reason why you cant see the ending triangle shape

Creating clickable linearlayout dynamically

I have to create LinearLayouts dinamically according to an Entity List. The Layouts are drawn without problems. My problem is when I try to know which Layout I have clicked, because always is referencing the last.
The code is something like this:
LinearLayout llProducts = FindViewById<LinearLayout>(Resource.Id.llProducts);
LinearLayout llNewProduct;
int i = 0;
foreach(Product p in productsList)
{
llNewProduct = new LinearLayout(this);
llNewProduct.Clickable = true;
llNewProduct.Id = i++;
TextView txtProduct = new TextView(this);
txtProduct.Text = p.Name;
llNewProduct.AddView(txtProduct);
llProducts.AddView(llNewProduct);
llNewProduct.Click += (sender, e)
{
//This always shows the last Id
Toast.MakeText(this, llNewProduct.Id.ToString(), ToastLength.Short).Show();
}
}
I appreciate some help. Thanks
You have to create Array of boolean sucg as boolean[] flag = new boolean[productList.length]. After this, you can set flag[i] = true when you set llNewProduct.Clickable = true; other set flag[i] =false;
After completion for each loop you can find out clicked lineanlayout with the help of this flag such as
for(int i=0;i<flag.length;i++){
if(flag[i]){
Log.v("TAG","Clicked linear layout");
}else{
Log.v("TAG","Not Clicked linear layout");
}
}
Use following code in foor loop
llNewProduct.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(YouActivity.this, ""+v.getId(), Toast.LENGTH_SHORT).show();
}
});
you are using same reference for all added view, create different views in side loop
Try like this:
for(int i1 = 0; i1 < 3;i1++)
{
LinearLayout llNewProduct = new LinearLayout(this);
LayoutParams p = new LayoutParams(100, 100);
llNewProduct.setLayoutParams(p);
if(i1 == 0) llNewProduct.setBackgroundColor(Color.RED);
if(i1 == 1) llNewProduct.setBackgroundColor(Color.GREEN);
if(i1 == 2) llNewProduct.setBackgroundColor(Color.BLUE);
llNewProduct.setClickable(true);
llNewProduct.setId(i1);
llNewProduct.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(CaptureImage.this, ""+v.getId(), Toast.LENGTH_SHORT).show();
}
});
ll1.addView(llNewProduct);
}
As I said on the last comment. The question is solved. Next code shows the id from layout clicked.
llNewProduct.Click += (sender, e)
{
LinearLayout ll = sender as LinearLayout;
Toast.MakeText(this, ll.Id.ToString(), ToastLength.Short).Show();
}

How to get elements from array list in android

Hi all in my application by using web service i get the data from database and stored that data in hash table.I took that data from hast table to array.this array data can be displayed in button.My array contains 10 elements.For animation i used view flipper.Now i want to do is display that array elements on button one after another for every 10sec.But in Updater method i didn't get all array elements.How to solve this one
i am sending my code
//in on create method i wore this one
user_advertise is the hash table
System.out.println(""+user_advertise.size());
array=new String[user_advertise.size()];
e= user_advertise.keys();
int i = 0;
int j=0;
for(i=user_advertise.size();;i++){
array[j]=e.nextElement().toString();
LinearLayout layout = (LinearLayout) findViewById(R.id.LinearLayout01);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
Button buttonView = new Button(this);
buttonView.setText("" +array[i]);
Timer timing = new Timer();
timing.schedule(new Updater(buttonView), 3000, 3000);
ViewFlipper flipper = new ViewFlipper (this);
flipper.addView(buttonView);
layout.addView(flipper,p);
flipper.startFlipping();
flipper.setClickable(true);
flipper.setFlipInterval(10000);
flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.push_left_in));
flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.push_left_out));
}
}catch(Exception e)
{
Log.v("Add",e.toString());
}
}
private class Updater extends TimerTask {
private final Button buttonView;
public Updater(Button buttonView) {
this.buttonView = buttonView;
}
public void run() {
buttonView.post(new Runnable() {
public void run() {
int k=0;
buttonView.setText(" ");
buttonView.setText(""+array[k].toString()+"");
if(array[++k]!= null)
{
k++;
}
}
You have defined and initialized int k=0; within the thread block so everytime it will run, k will always be 0 so you will have to define it outside.
Also
if(array[++k]!= null)
{
k++;
}
will increment k twice : one for the if test and one in the block
What you want is:
if(k != array.length - 1) k++;

Categories

Resources