Button OnClicklistener from dynamically genereated Buttons - android

I have a problem to build correct OnClicklistener for buttons I generate at runtime. I found some threads here on stackoverflow but after many tries I don't get it working.
I have a methode with builds a GUI with a TextView in left "column" and in right "column" x buttons. Each Button has an other link which should be open by onClick. I don't know the link before it's created at runtime.
Here my Code with my actuall try. But in this Case I get everytime only the link of the last generated button. If I click on first one, second one .... it's everytime the same link.
Hope there is a solution for it!
private void createNewView (String JsonInputBeacon, String JsonInputConfig){
TableLayout tableLayout = new TableLayout(this);
tableLayout.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT));
tableLayout.setStretchAllColumns(true);
try {
final JSONArray jsonArrayBeacon = new JSONArray(JsonInputBeacon);
final JSONArray jsonArrayConfig = new JSONArray(JsonInputConfig);
int Patientencounter = 1;
for(int JsonObjectCounterBeacon = 0; JsonObjectCounterBeacon < jsonArrayBeacon.length(); JsonObjectCounterBeacon ++ ){
final JSONObject objectBeacon = jsonArrayBeacon.getJSONObject(JsonObjectCounterBeacon);
TableRow row = new TableRow(this);
TextView outputLeft = new TextView(this);
outputLeft.setText("Patient " + Patientencounter + ":\n" + "Name: " + objectBeacon.getString("surname") + ", " + objectBeacon.getString("firstName") + "\n" + "Geb-Datum: " + objectBeacon.getString("birthdate"));
row.addView(outputLeft);
for (int JsonObjectCounterConfig = 0; JsonObjectCounterConfig < jsonArrayConfig.length(); JsonObjectCounterConfig++){
final JSONObject objectConfig = jsonArrayConfig.getJSONObject(JsonObjectCounterConfig);
TableRow rowRight = new TableRow(this);
Button buttonRight = new Button(getApplicationContext());
buttonRight.setText(objectConfig.getString("name"));
final String myURL = objectConfig.getString("link");
buttonRight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW,Uri.parse(myURL));
startActivity(browserIntent);
}
});
rowRight.addView(buttonRight);
row.addView(rowRight);
}
tableLayout.addView(row);
Patientencounter +=1;
}
} catch (JSONException e) {
e.printStackTrace();
}
setContentView(tableLayout);
}

But in this Case I get everytime only the link of the last generated
button. If I click on first one, second one .... it's everytime the
same link
Because myURLcontains value which is assigned by last iteration of for-loop.
Use setTag/getTag method of buttonRight to get url according to Button click. like:
Set value using setTag :
final String myURL = objectConfig.getString("link");
buttonRight.setTag(myURL);
and get myURL value using v parameter of onClick method:
Intent browserIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(v.getTag().toString()));

Set the tag of your button to be the URI, then access the tag from the view passed in to your onclick method.

Related

how pass from to another Layout using View.OnClickListener and dynamic buttons?

Hello, I create buttons dynamic and now I want when one of this buttons click, pass to another layout, but I can't! maybe somebody can give me solution, thank you
onCreate:
enter code here//-------------------Creating Buttons as per in server -------------------------------
final Button[] myButton = new Button[jsonArray.length()];
int count = jsonArray.length();
for (int i = 0; i < jsonArray.length(); i++) { //upside down -> HAFUH
// for (int i = jsonArray.length(); i > 0 ; i--) {
final Button rowButton = new Button(this);// create a new button
--count;//to upside down the buttons, that mean: check last will be on Top
// rowButton.setText(dateIn[count] + " KM: "+ kmIn[count]+" GAS: "+ gasIn[count]);
rowButton.setText( "KM: "+ kmIn[count]+" GAS: "+ gasIn[count]+" "+dateIn[count]);
rowButton.setId(Integer.parseInt(idIn[count]));//string convert to int "ID"
/*-----------Build onClick and what happened after ------------*/
rowButton.setOnClickListener(btnClick(myButton[i]));//WHEN Click on button
/*-------------FINISH Build onClick and what happened after---*/
b.addView(rowButton);
// save a reference to the button for later
myButton[i] = rowButton;
}//end for jsonArray
/************Finish Creating Buttons as per in server**********************************/
}//END IF FOR JSON AND BUILD BUTTON
}//End Create Button
outside onCreate method, in the class:
enter code hereprivate View.OnClickListener btnClick(final Button button) {
return new View.OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(this,GalleryHistoryCheckIn.class);
startActivity(intent);
}
};
}
I expect just pass to another class
HAHA I understand what was my problem, this is answer
method onCreate:
final Button[] myButton = new Button[jsonArray.length()];
int count = jsonArray.length();
for (int i = 0; i < jsonArray.length(); i++) { //upside down -> HAFUH
// for (int i = jsonArray.length(); i > 0 ; i--) {
final Button rowButton = new Button(this);// create a new button
--count;//to upside down the buttons, that mean: check last will be on Top
// rowButton.setText(dateIn[count] + " KM: "+ kmIn[count]+" GAS: "+ gasIn[count]);
rowButton.setText( "KM: "+ kmIn[count]+" GAS: "+ gasIn[count]+" "+dateIn[count]);
rowButton.setId(Integer.parseInt(idIn[count]));//string convert to int "ID"
/*-----------Build onClick and what happened after ------------*/
// rowButton.setOnClickListener(btnClick(myButton[i]));//WHEN Click on button
/*-------------FINISH Build onClick and what happened after---*/
b.addView(rowButton);
// save a reference to the button for later
myButton[i] = rowButton;
myButton[i].setOnClickListener(btnClick(rowButton));
}//end for jsonArray
/************Finish Creating Buttons as per in server**********************************/
}//END IF FOR JSON AND BUILD BUTTON
}//End Create Button
outside of on create but in class:
private View.OnClickListener btnClick(final Button button) {
return new View.OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(v.getContext(),GalleryHistoryCheckIn.class);
intent.putExtra("result", v.getId());
startActivity(intent);
}
};
}

How to find which dynamic button is clicked in android

i have created dynamic button in activity on button click. When i created more than on button in activity,onclick works for the most recent button as i assigned id to every button. how can i identify which dynamic button is pressed other than most recent button.
Here is the snippet of my code
public void dynamicButton()
{
// int x=0;
preferences = PreferenceManager.getDefaultSharedPreferences(TimeStudy.this);
value = preferences.getInt("value", 0);
//myButton = new Button(this);
// if (value > x)
if ( i <= value) {
myButton= new Button(this);
myButton.setId(value);
BtnId.add(value);
myButton.setTag(value);
LinearLayout ll = (LinearLayout) findViewById(R.id.dynamiclayout);
ll.setOrientation(LinearLayout.VERTICAL);
ll.setPadding(10, 300, 10, 10);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
myButton.setLayoutParams(lp);
btnid= myButton.getId();
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (btnid) {
case 1:case 2:case 3:case
Intent intent = new Intent(TimeStudy.this, CollectSample.class);
startActivity(intent);
break;
}
}
});
ll.addView(myButton, lp);
i++;
}
switch (btnid) {
case 1:case 2:case 3:
SharedPreferences average = getSharedPreferences("avg", 0);
String avgbtn = average.getString("btnavg", "");
settings = getSharedPreferences("dynamicbtname", 0);
btnname = settings.getString("btnname", "");
ar.add(btnname);
String styledText = "<font color='#008000'>" + btnname + "</font>" + "&nbsp" + "&nbsp" + "&nbsp"
+ "<small>"
+ avgbtn + "</font>"
+ "<small>";
myButton.setText(Html.fromHtml(styledText));
myButton.setGravity(Gravity.CENTER | Gravity.LEFT);
break;
}
i want result like this even if after creation of all three button and 1 button is clicked no shows on first button.
enter image description here
i get this if i pressed 1 button after creation of 2 or third button data returns to most recent button.
enter image description here
any help appriciated thanks in advance.
THere's two ways.
1)Check by comparing it to the view variable passed in
2)Use an OnClickListener implementation that knows which one it is (by using different classes, or using one class with a parameter in it).

How to set Views Vertically under each other Programmatically and Download file on Button Click

I have two questions
First, I have a for loop, with every element in this loop i want to set the Name String as a TextView and the Url to a Button,
Then to position those TextViews and Buttons vertically under each other Programmatically.
Second, i want those buttons to work for e.g if i click it then start downloading some from it's url.
To be clear this is my for loop
for(int i = 0; i < Array.length; i++) {
// This contains a String
String Name = "...";
// This contains a video url that i want to download onClick
String Url = "...";
}
What is the best way to do this?
create linearLayout and place your elements int it
do it like
for(int i = 0; i < Array.length; i++) {
// This contains a String
String Name = "...";
// This contains a video url that i want to download onClick
String Url = "...";
LinearLayout ll = new LinearLayout(context);
TextView tv = new TextView(context);
Button b = new Button(context);
ll.setOrientation(VERTICAL);
ll.addView(tv);
tv.setText(Name);
ll.addView(b);
b.setOnClickListener(View.OnClickListener() {
#Override
public void onClick(View v) {
downloadVideo(url);
}
});
addView(ll);
}
to Download url you can use alot of methods like the one mentioned here

How to add dynamic layout in existing layout ( Android, JSON )

I have an app in which I am showing data from JSON. I am displaying data in a dynamic textview on the right and left side of the relative layout. Now I want to add this layout in an existing layout so that I can apply an OnClickListener on the textview. Right now I am getting data into a string and then setting that string into static textviews in the left and right side of the layout.
How would it be possible to generate textview dynamically on the basis of number of data I am getting from JSON ?
for (Region object : temp.phonelist.regionList)
{
if (object.getCCInfoShortDesc() != null || !(object.getCCInfoShortDesc().equals(null)))
{
Log.i("nullexception", "nullexception");
holder.tvDescription.setText(object.getCCInfoShortDesc());
holder.tvDescription.setVisibility(View.VISIBLE);
}else {
Log.i("nullexception1", "nullexception1");
holder.tvDescription.setVisibility(View.GONE);
}
leftContent += object.getCCInfoLeft() + ":" + "\n";
rightContent += object.getCCInfoRight() + "\n";
}
Log.i("lefftcontent", leftContent);
Log.i("rightcontent", rightContent);
if (leftContent != null) {
holder.tvData2.setText(leftContent);
holder.tvData2.setVisibility(View.VISIBLE);
}
if (rightContent != null) {
holder.tvData1.setText(rightContent);
holder.tvData1.setVisibility(View.VISIBLE);
}
You can do it in this way..
final int Count = < Number of TextViews>; // total number of textviews to add
final TextView[] TextViewsARR = new TextView[N]; // create an empty array;
for (int i = 0; i < Count; i++) {
// create a new textview
final TextView rowTextView = new TextView(this);
// set some properties of rowTextView or something
rowTextView.setText("This is row #" + i);
// add the textview to the linearlayout
myLinearLayout.addView(rowTextView);
// save a reference to the textview for later
TextViewsARR [i] = rowTextView;
}
I have a sample below that generates a checkbox dynamically, If you
observe i am generating the checkbox based on the cursor count.
You can adapt this saple to your needs
Instead of checkbox use a texview
Give any layout like linear, relative etc and generate views
dynamically
private CheckBox chkBoxMealType[] = null;
mCursor = db.rawQuery("SELECT meal_type_id,meal_type_name FROM meal_type_mas", null);
if(mCursor.moveToFirst()){
do{
if(chkBoxMealTypeCnt==0){
chkBoxMealType=new CheckBox[mCursor.getCount()];
}
//create a general view for checkbox
chkBoxMealType[chkBoxMealTypeCnt]= new CheckBox(getActivity());
//Create params for veg-checkbox
//Reason:: we don't need to worry about the data exist in cuisine_type_mas table
chkBoxMealType[chkBoxMealTypeCnt].setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
chkBoxMealType[chkBoxMealTypeCnt].setTextColor(getResources().getColor(R.color.searchGoldLight));
chkBoxMealType[chkBoxMealTypeCnt].setTextSize(TypedValue.COMPLEX_UNIT_SP,12);
chkBoxMealType[chkBoxMealTypeCnt].setTag(mCursor.getString(mCursor.getColumnIndexOrThrow(meal_type_mas.COLUMN_MEAL_TYPE_ID)));
chkBoxMealType[chkBoxMealTypeCnt].setText(WordUtils.capitalizeFully(mCursor.getString(mCursor.getColumnIndexOrThrow(meal_type_mas.COLUMN_MEAL_TYPE_NAME))));
mealTypeContainer.addView(chkBoxMealType[chkBoxMealTypeCnt]);
//since cursor count starts from 0 last count must be allowed
chkBoxMealTypeCnt++;
}while(mCursor.moveToNext());
Log.d("", "");
}
I have another sample..... Download this project(Click Here) and run in your editor
Snapshot::
Firstly you need to add a View in your layout ... Like you may try using LinearLayout or HorizontalLayout ... and then attach/add your dynamic textview to that layout.
Pragmatically you may try like this
packageButtons = new ArrayList<TextView>(); // Create your textview arraylist like this
for(int a = 0; a < your_text_view_from_json.size(); a++){
final TextView rowTextView;
rowTextView = new TextView(getApplicationContext());
rowTextView.setText(taxi_type_spin.get(a).taxi_type);
rowTextView.setTextSize(15);
rowTextView.setTextColor(getResources().getColor(R.color.white));
LinearLayout.LayoutParams lparam = new LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
//rowTextView.setPadding(0, 0, 0, 0);
packageButtons.add(rowTextView);
rowTextView.setLayoutParams(lparam);
rowTextView.setId(a);
final int b = a;
// get value of clicked item over here ..
rowTextView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Button btn = (Button)v;
String get_value = btn.getText().toString();
//Toast.makeText(getApplicationContext(), "Button name is : " + get_value + " AND ID IS : " + rowTextView.getId(), Toast.LENGTH_LONG).show();
if(taxi_type_spin.get(b).taxi_type.equalsIgnoreCase(Utils.Hourly_Package))
{
setTaxiType(rowTextView.getId(),true);
ll_spin.setVisibility(View.VISIBLE);
}
else
{
setTaxiType(rowTextView.getId(),false);
ll_spin.setVisibility(View.GONE);
}
setSelectedButtonColor(b);
}
});
// add the textview to the linearlayout
myLinearLayout.addView(rowTextView);
NOTE rowTextView .. this is your default view attached to your XML file
Hope it helps!
private void setLayout(LinearLayout llayout,
final ArrayList<String> items) {
for (int i = 0; i < items.size(); i++) {
LinearLayout row = null;
LayoutInflater li = getLayoutInflater();
row = (LinearLayout) li.inflate(R.layout.custom_item,
null);
ImageView image = (ImageView) row.findViewById(R.id.image);
llayout.addView(row);
}
}
I would suggest you to use ArrayList, because the class java.util.ArrayList provides resizable-array, which means that items can be added and removed from the list dynamically.
and get value from ArrayList something like this:
for(int i=0; i<arrayList.size(); i++)
{
textName.setText(object.getName());
}
How it is possible to genrate textview dynamically
on the basis of number of data i am getting from json.
You need to create TextView and add it to the parent layout each time you iterate on the forloop. So you will have textView for each of the element of the temp.phonelist.regionList
sample:
for (Region object : temp.phonelist.regionList)
{
TextView tx = new TextView(context); //creating a new instance if textview
//yourstuff goes here
tx.setText(text_you_want);
yourView.addView(tx); //this is to add the textView on each iteration
}
here is your solution do this way,Take one Layout(Linear or Relative) and add control dynamically....
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
for (int i = 0; i < 4; i++)
{
TextView txtDemo = new TextView(getActivity());
txtDemo .setTextSize(16);
txtDemo .setLayoutParams(lp);
txtDemo .setId(i);
lp.setMargins(0, 10, 0, 0);
txtDemo .setPadding(20, 10, 10, 10);
txtDemo .setText("Text View"+ i);
linearlayout.addView(txtDemo );
}
}

a Looped OnClickListener always gets the wrong index array

I have this loop method to display a ViewPager and I set an OnClickListener for each Image on the ViewPager. So when the image is clicked, the user will be brought to a VideoPlayer class. but I don't know why, the footage_video_url[i] on putExtra() of the click listener always reads that the i on the extra is the maximum length. So the i always exceeds the maximum array length and that makes the app crash.
What I was expecting is, if for example the displayed image is footage_thumbnail_url[1], the String which is put on extra is footage_video_url[1] respectively, and so on.
Does anybody know where I go wrong?
for(i = 0; i < length; i++){
final String[] video_url = footage_video_url;
final String[] thumbnail_url = footage_thumbnail_url;
//System.out.println("FOOTAGE VIDEO DETAILS " +i+ ": " +video_url[i]);
FrameLayout content = new FrameLayout(this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
(int) size, (int) size);
params.gravity = Gravity.CENTER;
ImageView imageView = new ImageView(this);
ImageLoader loader = new ImageLoader(this);
// Image from URL
if (footage_thumbnail_url[i].contains("http"))
loader.downloadPicture(imageView, footage_thumbnail_url,i);
else {
// Image From SDCard
File imgFile = new File(thumbnail_url[i]);
Bitmap bitmapImage = loader.decodeFile(imgFile);
Drawable drawableImage = new BitmapDrawable(bitmapImage);
imageView.setBackgroundDrawable(drawableImage);
imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent listIntent = new Intent(getApplicationContext(),
VideoPlayer.class);
listIntent.putExtra("video_url", footage_video_url[i]);
System.out.println("Video Number "+i+" : "+ footage_video_url[i]);
startActivity(listIntent);
}
});
}
content.addView(imageView);
View overlay = new View(this);
overlay.setBackgroundResource(R.drawable.btn_play);
params.gravity = Gravity.CENTER;
overlay.setLayoutParams(params);
overlay.invalidate();
content.addView(overlay);
pagerViews.add(content);
}
Try to set as the tag for the ImageView the string footage_video_url[i] and then retrieve it in the OnClickListener. This way you're sure the correct String will be put in the extras:
imageView.setTag(footage_video_url[i]);
imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String theUrl = (String) v.getTag(); // I hope it's a String
Intent listIntent = new Intent(getApplicationContext(),
VideoPlayer.class);
listIntent.putExtra("video_url", theUrl);
System.out.println("Video Number "+i+" : "+ theUrl);
startActivity(listIntent);
}
});
Take imageView as an array of length n. Then before your for loop, add 1 more for loop where u'll set the tags for all the 'n' imageViews, something like this:
for(int x=0;x<length;x++)
imageView[x].setTag(x);
then inside your loop replace these lines:
listIntent.putExtra("video_url", footage_video_url[i]);
System.out.println("Video Number "+i+" : "+ footage_video_url[i]);
with these lines:
listIntent.putExtra("video_url", footage_video_url[imageView[i].getTag(i)]);
System.out.println("Video Number "+i+" : "+ footage_video_url[imageView[i].getTag(i)]);
Hope this might help !!

Categories

Resources