How to update linearlayout child view programmatically in android? - 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.

Related

putExtra on dynamically created views android

I have a list of Strings. I am adding a RelativeLayout dynamically for each of them and adding TextViews dynamically in each of the relativelayouts. Now when I click, I am sending this textview value to the next activity. Below is the code.
for(int i = 0; i < Names.size(); i++)
{
textView = new TextView(this);
textView.setText(Names.get(i));
rt=new RelativeLayout(this);
rt.setBackgroundResource(R.drawable.mednamedash);
int curTextViewId = prevTextViewId + 1;
int curRLId = prevRLId + 1;
textView.setId(curTextViewId);
rt.setId(curRLId);
final RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, prevTextViewId);
final RelativeLayout.LayoutParams tvParams =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
tvParams.addRule(RelativeLayout.CENTER_IN_PARENT);
rt.addView(textView, tvParams);
prevTextViewId = curTextViewId;
prevRLId=curRLId;
noon.addView(rt, params);
rt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(Dashboard.this,ReminderPopUp.class);
i.putExtra("medicinename", textView.getText().toString());
startActivity(i);
}
});
}
The problem is that if I have 10 RelativeLayouts with different texts and I am clicking on anyone of them, no matter which one I am clicking, only the last value of textview is passed to the next activity; not the value for which I clicked.
Please help
Thank you
You are getting always the last one because you are overriding the member class at every iteration of the loop.
you could set the OnClickListener to the TextView instead of the RelativeLayout and cast v, the clicked View, to TextView
textView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(Dashboard.this,ReminderPopUp.class);
i.putExtra("medicinename", ((TextView)v).getText().toString());
startActivity(i);
}
});
try to use the clicked view which is your textview for that change your code to this.By following so you will get the context of currently clicked textview not the last one.
rt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
TextView txt=(TextView)v;
Intent i=new Intent(Dashboard.this,ReminderPopUp.class);
i.putExtra("medicinename", txt.getText().toString());
startActivity(i);
}
});
In onClick, get the text view from the relative layout as
TextView textView = (TextView) rl.getChildAt(0);
String name= textView.getText().toString();

setText on TextViews created using a for loop - android

I have created a set of TextViews programmatically using a for loop. This what i have tried.
for(int i=1; i<5; i++){
valueTV = new TextView(AddMyVehicle.this);
linearLayout.addView(valueTV);
vehicleModelReturned = myVehicleData.getString("VehicleModel"+x, "");
valueTV.setText(vehicleModelReturned);
valueTV.setGravity(Gravity.CENTER_HORIZONTAL);
valueTV.setTextSize(TypedValue.COMPLEX_UNIT_SP,22);
valueTV.setTextColor(Color.parseColor("#333333"));
i++;
}
this.valueTV.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
valueTV.setText("Hello");
}
});
I need to change the text of clicked TextView to "Hello". How can i achieve this?
You have to add a listener to all your TextView created.
And be careful, you incremented i twice : one in the first line of the for and another one in the end of the for.
for (int i = 1; i < 5; i++)
{
final TextView valueTV = new TextView(AddMyVehicle.this);
linearLayout.addView(valueTV);
vehicleModelReturned = myVehicleData.getString("VehicleModel" + x, "");
valueTV.setText(vehicleModelReturned);
valueTV.setGravity(Gravity.CENTER_HORIZONTAL);
valueTV.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22);
valueTV.setTextColor(Color.parseColor("#333333"));
valueTV.setId("test");
valueTV.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
TextView tv = (TextView) v;
tv.setText("Hello");
}
});
}
First, set the OnClickListener to all the TextViews you create, not just the last one. That is, move the setOnClickListener() inside the for loop.
Second, in onClick(), change the text of the clicked view and not again the last one you created. The View v param is the view that was clicked. You can cast it to TextView.

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

UI Block on creating imageview at runtime

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.

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();
}

Categories

Resources