Add and Remove Views in Android Dynamically? - android

How do I add and remove views such as TextViews from Android app like on the original stock Android contacts screen where you press a small icon on the right side of a field and it adds or deletes a field which consists of a TextView and an editTextView (from what I can see).
Any examples on how to achieve this?

ViewParents in general can't remove views, but ViewGroups can. You need to cast your parent to a ViewGroup (if it is a ViewGroup) to accomplish what you want.
For example:
View namebar = View.findViewById(R.id.namebar);
((ViewGroup) namebar.getParent()).removeView(namebar);
Note that all Layouts are ViewGroups.

I need the exact same feature described in this question. Here is my solution and source code: https://github.com/laoyang/android-dynamic-views. And you can see the video demo in action here: http://www.youtube.com/watch?v=4HeqyG6FDhQ
Layout
Basically you'll two xml layout files:
A horizontal LinearLayout row view with a TextEdit, a Spinner and an ImageButton for deletion.
A vertical LinearLayout container view with just a Add new button.
Control
In the Java code, you'll add and remove row views into the container dynamically, using inflate, addView, removeView, etc. There are some visibility control for better UX in the stock Android app. You need add a TextWatcher for the EditText view in each row: when the text is empty you need to hide the Add new button and the delete button. In my code, I wrote a void inflateEditRow(String) helper function for all the logic.
Other tricks
Set android:animateLayoutChanges="true" in xml to enable animation
Use custom transparent background with pressed selector to make the buttons visually the same as the ones in the stock Android app.
Source code
The Java code of the main activity ( This explains all the logic, but quite a few properties are set in xml layout files, please refer to the Github source for complete solution):
public class MainActivity extends Activity {
// Parent view for all rows and the add button.
private LinearLayout mContainerView;
// The "Add new" button
private Button mAddButton;
// There always should be only one empty row, other empty rows will
// be removed.
private View mExclusiveEmptyView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.row_container);
mContainerView = (LinearLayout) findViewById(R.id.parentView);
mAddButton = (Button) findViewById(R.id.btnAddNewItem);
// Add some examples
inflateEditRow("Xiaochao");
inflateEditRow("Yang");
}
// onClick handler for the "Add new" button;
public void onAddNewClicked(View v) {
// Inflate a new row and hide the button self.
inflateEditRow(null);
v.setVisibility(View.GONE);
}
// onClick handler for the "X" button of each row
public void onDeleteClicked(View v) {
// remove the row by calling the getParent on button
mContainerView.removeView((View) v.getParent());
}
// Helper for inflating a row
private void inflateEditRow(String name) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.row, null);
final ImageButton deleteButton = (ImageButton) rowView
.findViewById(R.id.buttonDelete);
final EditText editText = (EditText) rowView
.findViewById(R.id.editText);
if (name != null && !name.isEmpty()) {
editText.setText(name);
} else {
mExclusiveEmptyView = rowView;
deleteButton.setVisibility(View.INVISIBLE);
}
// A TextWatcher to control the visibility of the "Add new" button and
// handle the exclusive empty view.
editText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// Some visibility logic control here:
if (s.toString().isEmpty()) {
mAddButton.setVisibility(View.GONE);
deleteButton.setVisibility(View.INVISIBLE);
if (mExclusiveEmptyView != null
&& mExclusiveEmptyView != rowView) {
mContainerView.removeView(mExclusiveEmptyView);
}
mExclusiveEmptyView = rowView;
} else {
if (mExclusiveEmptyView == rowView) {
mExclusiveEmptyView = null;
}
mAddButton.setVisibility(View.VISIBLE);
deleteButton.setVisibility(View.VISIBLE);
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
});
// Inflate at the end of all rows but before the "Add new" button
mContainerView.addView(rowView, mContainerView.getChildCount() - 1);
}

This is my general way:
View namebar = view.findViewById(R.id.namebar);
ViewGroup parent = (ViewGroup) namebar.getParent();
if (parent != null) {
parent.removeView(namebar);
}

Hi You can try this way by adding relative layout and than add textview in that.
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
(LayoutParams.WRAP_CONTENT), (LayoutParams.WRAP_CONTENT));
RelativeLayout relative = new RelativeLayout(getApplicationContext());
relative.setLayoutParams(lp);
TextView tv = new TextView(getApplicationContext());
tv.setLayoutParams(lp);
EditText edittv = new EditText(getApplicationContext());
edittv.setLayoutParams(lp);
relative.addView(tv);
relative.addView(edittv);

Just use myView.setVisibility(View.GONE); to remove it completely.
But if you want to reserve the occupied space inside its parent use myView.setVisibility(View.INVISIBLE);

Kotlin Extension Solution
Add removeSelf to directly call on a view. If attached to a parent, it will be removed. This makes your code more declarative, and thus readable.
myView.removeSelf()
fun View?.removeSelf() {
this ?: return
val parent = parent as? ViewGroup ?: return
parent.removeView(this)
}
Here are 3 options for how to programmatically add a view to a ViewGroup.
// Built-in
myViewGroup.addView(myView)
// Reverse addition
myView.addTo(myViewGroup)
fun View?.addTo(parent: ViewGroup?) {
this ?: return
parent ?: return
parent.addView(this)
}
// Null-safe extension
fun ViewGroup?.addView(view: View?) {
this ?: return
view ?: return
addView(view)
}

ViewGroup class provides API for child views management in run-time, allowing to add/remove views as well.
Some other links on the subject:
Android, add new view without XML Layout
Android Runtime Layout Tutorial
http://developer.android.com/reference/android/view/View.html
http://developer.android.com/reference/android/widget/LinearLayout.html

For Adding the Button
LinearLayout dynamicview = (LinearLayout)findViewById(R.id.buttonlayout);
LinearLayout.LayoutParams lprams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Button btn = new Button(this);
btn.setId(count);
final int id_ = btn.getId();
btn.setText("Capture Image" + id_);
btn.setTextColor(Color.WHITE);
btn.setBackgroundColor(Color.rgb(70, 80, 90));
dynamicview.addView(btn, lprams);
btn = ((Button) findViewById(id_));
btn.setOnClickListener(this);
For removing the button
ViewGroup layout = (ViewGroup) findViewById(R.id.buttonlayout);
View command = layout.findViewById(count);
layout.removeView(command);

Hi First write the Activity class. The following class have a Name of category and small add button. When you press on add (+) button it adds the new row which contains an EditText and an ImageButton which performs the delete of the row.
package com.blmsr.manager;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import com.blmsr.manager.R;
import com.blmsr.manager.dao.CategoryService;
import com.blmsr.manager.models.CategoryModel;
import com.blmsr.manager.service.DatabaseService;
public class CategoryEditorActivity extends Activity {
private final String CLASSNAME = "CategoryEditorActivity";
LinearLayout itsLinearLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category_editor);
itsLinearLayout = (LinearLayout)findViewById(R.id.linearLayout2);
}
#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_category_editor, 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.
switch (item.getItemId()) {
case R.id.action_delete:
deleteCategory();
return true;
case R.id.action_save:
saveCategory();
return true;
case R.id.action_settings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Adds a new row which contains the EditText and a delete button.
* #param theView
*/
public void addField(View theView)
{
itsLinearLayout.addView(tableLayout(), itsLinearLayout.getChildCount()-1);
}
// Using a TableLayout as it provides you with a neat ordering structure
private TableLayout tableLayout() {
TableLayout tableLayout = new TableLayout(this);
tableLayout.addView(createRowView());
return tableLayout;
}
private TableRow createRowView() {
TableRow tableRow = new TableRow(this);
tableRow.setPadding(0, 10, 0, 0);
EditText editText = new EditText(this);
editText.setWidth(600);
editText.requestFocus();
tableRow.addView(editText);
ImageButton btnGreen = new ImageButton(this);
btnGreen.setImageResource(R.drawable.ic_delete);
btnGreen.setBackgroundColor(Color.TRANSPARENT);
btnGreen.setOnClickListener(anImageButtonListener);
tableRow.addView(btnGreen);
return tableRow;
}
/**
* Delete the row when clicked on the remove button.
*/
private View.OnClickListener anImageButtonListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
TableRow anTableRow = (TableRow)v.getParent();
TableLayout anTable = (TableLayout) anTableRow.getParent();
itsLinearLayout.removeView(anTable);
}
};
/**
* Save the values to db.
*/
private void saveCategory()
{
CategoryService aCategoryService = DatabaseService.getInstance(this).getCategoryService();
aCategoryService.save(getModel());
Log.d(CLASSNAME, "successfully saved model");
Intent anIntent = new Intent(this, CategoriesListActivity.class);
startActivity(anIntent);
}
/**
* performs the delete.
*/
private void deleteCategory()
{
}
/**
* Returns the model object. It gets the values from the EditText views and sets to the model.
* #return
*/
private CategoryModel getModel()
{
CategoryModel aCategoryModel = new CategoryModel();
try
{
EditText anCategoryNameEditText = (EditText) findViewById(R.id.categoryNameEditText);
aCategoryModel.setCategoryName(anCategoryNameEditText.getText().toString());
for(int i= 0; i< itsLinearLayout.getChildCount(); i++)
{
View aTableLayOutView = itsLinearLayout.getChildAt(i);
if(aTableLayOutView instanceof TableLayout)
{
for(int j= 0; j< ((TableLayout) aTableLayOutView).getChildCount() ; j++ );
{
TableRow anTableRow = (TableRow) ((TableLayout) aTableLayOutView).getChildAt(i);
EditText anEditText = (EditText) anTableRow.getChildAt(0);
if(StringUtils.isNullOrEmpty(anEditText.getText().toString()))
{
// show a validation message.
//return aCategoryModel;
}
setValuesToModel(aCategoryModel, i + 1, anEditText.getText().toString());
}
}
}
}
catch (Exception anException)
{
Log.d(CLASSNAME, "Exception occured"+anException);
}
return aCategoryModel;
}
/**
* Sets the value to model.
* #param theModel
* #param theFieldIndexNumber
* #param theFieldValue
*/
private void setValuesToModel(CategoryModel theModel, int theFieldIndexNumber, String theFieldValue)
{
switch (theFieldIndexNumber)
{
case 1 :
theModel.setField1(theFieldValue);
break;
case 2 :
theModel.setField2(theFieldValue);
break;
case 3 :
theModel.setField3(theFieldValue);
break;
case 4 :
theModel.setField4(theFieldValue);
break;
case 5 :
theModel.setField5(theFieldValue);
break;
case 6 :
theModel.setField6(theFieldValue);
break;
case 7 :
theModel.setField7(theFieldValue);
break;
case 8 :
theModel.setField8(theFieldValue);
break;
case 9 :
theModel.setField9(theFieldValue);
break;
case 10 :
theModel.setField10(theFieldValue);
break;
case 11 :
theModel.setField11(theFieldValue);
break;
case 12 :
theModel.setField12(theFieldValue);
break;
case 13 :
theModel.setField13(theFieldValue);
break;
case 14 :
theModel.setField14(theFieldValue);
break;
case 15 :
theModel.setField15(theFieldValue);
break;
}
}
}
2. Write the Layout xml as given below.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#006699"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.blmsr.manager.CategoryEditorActivity">
<LinearLayout
android:id="#+id/addCategiryNameItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/categoryNameTextView"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="#string/lbl_category_name"
android:textStyle="bold"
/>
<TextView
android:id="#+id/categoryIconName"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="#string/lbl_category_icon_name"
android:textStyle="bold"
/>
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="#+id/categoryNameEditText"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="#string/lbl_category_name"
android:inputType="textAutoComplete" />
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
<ImageButton
android:id="#+id/addField"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="#+id/addCategoryLayout"
android:src="#drawable/ic_input_add"
android:onClick="addField"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
Once you finished your view will as shown below

//MainActivity :
package com.edittext.demo;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText edtText;
private LinearLayout LinearMain;
private Button btnAdd, btnClear;
private int no;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtText = (EditText)findViewById(R.id.edtMain);
btnAdd = (Button)findViewById(R.id.btnAdd);
btnClear = (Button)findViewById(R.id.btnClear);
LinearMain = (LinearLayout)findViewById(R.id.LinearMain);
btnAdd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!TextUtils.isEmpty(edtText.getText().toString().trim())) {
no = Integer.parseInt(edtText.getText().toString());
CreateEdittext();
}else {
Toast.makeText(MainActivity.this, "Please entere value", Toast.LENGTH_SHORT).show();
}
}
});
btnClear.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
LinearMain.removeAllViews();
edtText.setText("");
}
});
/*edtText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});*/
}
protected void CreateEdittext() {
final EditText[] text = new EditText[no];
final Button[] add = new Button[no];
final LinearLayout[] LinearChild = new LinearLayout[no];
LinearMain.removeAllViews();
for (int i = 0; i < no; i++){
View view = getLayoutInflater().inflate(R.layout.edit_text, LinearMain,false);
text[i] = (EditText)view.findViewById(R.id.edtText);
text[i].setId(i);
text[i].setTag(""+i);
add[i] = (Button)view.findViewById(R.id.btnAdd);
add[i].setId(i);
add[i].setTag(""+i);
LinearChild[i] = (LinearLayout)view.findViewById(R.id.child_linear);
LinearChild[i].setId(i);
LinearChild[i].setTag(""+i);
LinearMain.addView(view);
add[i].setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Toast.makeText(MainActivity.this, "add text "+v.getTag(), Toast.LENGTH_SHORT).show();
int a = Integer.parseInt(text[v.getId()].getText().toString());
LinearChild[v.getId()].removeAllViews();
for (int k = 0; k < a; k++){
EditText text = (EditText) new EditText(MainActivity.this);
text.setId(k);
text.setTag(""+k);
LinearChild[v.getId()].addView(text);
}
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
// Now add xml main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<EditText
android:id="#+id/edtMain"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_weight="1"
android:ems="10"
android:hint="Enter value" >
<requestFocus />
</EditText>
<Button
android:id="#+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="Add" />
<Button
android:id="#+id/btnClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:text="Clear" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" >
<LinearLayout
android:id="#+id/LinearMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
// now add view xml file..
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<EditText
android:id="#+id/edtText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:ems="10" />
<Button
android:id="#+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="Add" />
</LinearLayout>
<LinearLayout
android:id="#+id/child_linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:orientation="vertical" >
</LinearLayout>

Related

App force close when changing items in StringArray, Android?

right now I'm working on a app which changes items in StringArray on button clicks. I've implemented left and right buttons, when I click right button the item changes by right, when I press left the item changes to left. Up to here everything is fine, but when I click left button when the item is on Steve Jobs the app force closes. Any idea why this is happening?
Strings.xml:
<string name="sj">Steve Jobs</string>
<string name="mz">Mark Zuckerberg</string>
<string name="bg">Bill Gates</string>
<string name="lp">Larry Page</string>
<string-array name="gl">
<item>#string/sj</item>
<item>#string/mz</item>
<item>#string/bg</item>
<item>#string/lp</item>
</string-array>
MainActivity.java:
package com.example.theatremode;
import android.support.v7.app.ActionBarActivity;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity implements OnClickListener {
int counter = 0;
TextView tv1;
Button button1;
Button button2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.tv1);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
Resources res = getResources();
final String[] list = res.getStringArray(R.array.gl); // get the array
((TextView) findViewById(R.id.tv1)).setText(list[counter]); // set the
// initial
// message.
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView tx = (TextView) findViewById(R.id.tv1);
counter++;
if (counter >= list.length)
counter = 0;
tx.setText(list[counter]); // set the new message.
}
});
Resources res2 = getResources();
final String[] list2 = res2.getStringArray(R.array.gl); // get the array
((TextView) findViewById(R.id.tv1)).setText(list2[counter]);
button2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView tx2 = (TextView) findViewById(R.id.tv1);
counter--;
if (counter >= list2.length)
counter = 0;
tx2.setText(list2[counter]); // set the new message.
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.theatremode.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:id="#+id/tv1"/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button1"
android:layout_alignBottom="#+id/button1"
android:layout_alignLeft="#+id/tv1"
android:text="Left" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="48dp"
android:layout_marginRight="14dp"
android:text="Right" />
Looks like you have a IndexOutOfBoundsException.
It's not obvious exactly what's going on here, but this might fix it:
button2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView tx2 = (TextView) findViewById(R.id.tv1);
counter--;
//if (counter >= list2.length)
//counter = 0;
if (counter < 0)
counter = list2.length - 1;
tx2.setText(list2[counter]); // set the new message.
}
});

show EditText on condition

Right now I have an idea for a project and I would like to know if anyone can help me on the same logic.
As such I need to create or generate a number of EditText according to amount you enter, ie, to select or enter a number such as 5, show me 5 EditText layout for type 5 values​​. They know that the form could accomplish this? Any ideas please?
I guess it must be a way to do it with a loop, but not like carrying this calculation Java to XML. Thank you.
Here is an example of generating EditText items based on the number you enter. You can ignore the scrollview in the layout file I just put it in case someone added a lot of EditText items that would go off the screen.
MainActivity.java
package com.example.test;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
public class MainActivity extends Activity {
public static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText count = (EditText) findViewById(R.id.count);
final TextView output = (TextView) findViewById(R.id.output);
final Button generate = (Button) findViewById(R.id.generate);
final Button values = (Button) findViewById(R.id.values);
final LinearLayout container = (LinearLayout) findViewById(R.id.container);
generate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int numberOfControlsToGenerate = 0;
try {
numberOfControlsToGenerate = Integer.parseInt(count.getText().toString().trim());
} catch (NumberFormatException e) {
Log.e(TAG, e.getMessage(), e);
}
if (numberOfControlsToGenerate > 0) {
if (container.getChildCount() > 0) {
container.removeAllViews();
}
for (int counter = 0; counter < numberOfControlsToGenerate; counter++) {
addEditText(container);
}
}
}
});
values.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String[] editTextValues = new String[container.getChildCount()];
StringBuilder editTextValuesBuilder = new StringBuilder();
for (int counter = 0; counter < container.getChildCount(); counter++) {
EditText child = (EditText) container.getChildAt(counter);
editTextValues[counter] = child.getText().toString().trim();
editTextValuesBuilder.append(editTextValues[counter]).append("\n");
}
output.setText(editTextValuesBuilder.toString());
}
});
}
private void addEditText(LinearLayout container) {
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
EditText editTextToAdd = new EditText(this);
editTextToAdd.setLayoutParams(params);
container.addView(editTextToAdd);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp"
tools:context="${packageName}.${activityClass}" >
<EditText
android:id="#+id/count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="number"
android:textSize="20sp" />
<Button
android:id="#+id/generate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go" />
<Button
android:id="#+id/values"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Values" />
<TextView
android:id="#+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
</LinearLayout>

Android onclick Buttons Sequence

I have 5 buttons every one has letter (Button "H",Button "E"Button "L"Button "L"Button "O") which make the word "HELLO". what I need is to make on click sequence to these buttons so if I click "H" first and "E" second until complete the word the app will do something, But if I click "L" first will give me some error message.
Any Idea to do this sequence?
Thanks
Just have an Array like this:
int[] tracker = new int[5];
and when you click a button, say "H", set tracker[0] = 1;
but when you click a button, say "L", check whether all the previous button values are 1. If yes, then set the corresponding tracker to 1 else, show an error message, and do not make any change to the tracker Array.
Something Like this:
onHClick{
tracker[0] = 1;
}
onEClick{
for(int i=0; i<1; i++){
if(tracker[i] == 0){
//show error message and return;
}else{
tracker[1] = 1;
return;
}
}
}
You can do something like
When activity started you just make other button Enabled = false of something like that. But make the first button Enabled. Don't make the Visible=false.
Now on click of Button "H" make enable Button "E" and so on.
So user will only have to click the button in sequence. Button can not be presses in any random manner.
Try this and let me know that it works or not.
Very Interesting and exactly same to your requirement..check once..
If you give any string other than HELLO also works better.
public class ButtonTest extends Activity
{
private String result="";
String sampleText = "HELLO";
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
int noOfBtns = sampleText.length();
LinearLayout ll = (LinearLayout)findViewById(R.id.btnlay);
final TextView tvtext = (TextView)findViewById(R.id.result);
final Button[] btns = new Button[noOfBtns];
for(int i=0;i<noOfBtns;i++)
{
btns[i] = new Button(this);
btns[i].setText(sampleText.substring(i,i+1));
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
ll.addView(btns[i], lp);
final int j = i;
btns[i].setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
System.out.println(j+" "+result.length());
if(j == result.length())
{
result = result+btns[j].getText().toString();
if(sampleText.startsWith(result))
{
tvtext.setText(result);
}
}
else
{
Toast.makeText(getApplicationContext(), "Wrong Button Pressed", Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
Layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/result"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:textColor="#fff"/>
<LinearLayout
android:id="#+id/btnlay"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
Try the following
package com.example.buttonsequence;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
{
ArrayList<Button> buttonList=null;
TextView resultTextView=null;
Button buttons[]=null;
String helloStr="HELLO";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonList=new ArrayList<Button>();
buttons=new Button[5];
this.resultTextView=(TextView) this.findViewById(R.id.result_text);
this.resultTextView.setText("");
buttons[0]=(Button)this.findViewById(R.id.h_button);
buttons[1]=(Button)this.findViewById(R.id.e_button);
buttons[2]=(Button)this.findViewById(R.id.l_button);
buttons[3]=(Button)this.findViewById(R.id.l2_button);
buttons[4]=(Button)this.findViewById(R.id.o_button);
for(int k=0;k<5;k++)
buttons[k].setOnClickListener(onClickListener);
Button button=(Button)this.findViewById(R.id.exit_button);
button.setOnClickListener
(
new OnClickListener()
{
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
}
);
}
OnClickListener onClickListener=new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
Button b=(Button)v;
buttonList.add(b);
int size=buttonList.size();
if(size>0)
{
StringBuilder resultBuilder=new StringBuilder();
for(int i=0;i<size;i++)
{
Button tempButton=buttonList.get(i);
if(tempButton==buttons[i])
{
resultBuilder.append(helloStr.charAt(i));
if(i==4)
{
resultTextView.setText(resultBuilder.toString()+" clicked");
buttonList.clear();
}
else
{
resultTextView.setText(resultBuilder.toString()+" clicked");
}
}
else
{
buttonList.remove(i);
Toast.makeText(getApplicationContext(), "No correctly clicked", Toast.LENGTH_SHORT).show();
break;
}
}
}
else
{
resultTextView.setText("Invalid pressed");
}
}
};
}
activity_main.xml
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<Button
android:id="#+id/h_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="H" />
<Button
android:id="#+id/e_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="E" />
<Button
android:id="#+id/l_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="L" />
<Button
android:id="#+id/l2_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="L" />
<Button
android:id="#+id/o_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="O" />
<TextView
android:id="#+id/result_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:id="#+id/exit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Exit" />
</LinearLayout>
I don't know exactly your flow but you can try this.
set Tag to each button as its Text, like this.
b.setTag("H");
and than after like this.
Button b;
String name = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String s = (String) v.getTag();
name +=s;
if( "HELLO".startsWith(name)){
<VALID>
}else{
<ERROR>
}
}
});
}
check the variable name on each button click with your original word i.e. HELLO like above.

Delete button in TableRow

I have an Edit button in my header. And I populating my TableLayout in a loop. In The loop I am inflating a Delete button.
Following is the code I have used :
MainActivity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cookbooklist);
btnHeaderEdit = (Button)findViewById(R.id.btnEdit);
btnHeaderEdit.setVisibility(View.VISIBLE);
delete_button = (View)findViewById(R.id.btnDelete);
listTable = (TableLayout)findViewById(R.id.cookbookListTable);
btnHeaderEdit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
delete_button.getTag();
delete_button.setVisibility(View.VISIBLE);
}
});
for(int i=0;i<=10;i++)
{
// Row to display news title
final TableRow newsRow = new TableRow(this);
newsRow.setMinimumHeight(200);
newsRow.setClickable(true);
newsRow.setTag(i);
newsRow.setBackgroundColor(Color.WHITE);
// Some other views
//create inflater
LayoutInflater inflater = getLayoutInflater();
delete_button = inflater.inflate(R.layout.deletebutton,
(ViewGroup) newsRow, false);
delete_button.setTag(i);
delete_button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
listTable.removeView(newsRow);
}
});
//Add views in table
newsRow.addView(delete_button);
listTable.addView(newsRow);
}
}
delebutton.xml :
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/btnDelete"
android:layout_width="100dip"
android:visibility="invisible"
android:layout_height="40dip"
android:padding="10sp"
android:text="Delete">
</Button>
Question :
The problem I am facing is that when I click the Edit button in header, Delete button appears only in the last row. When I setVisibility of Delete button to Visible in layout, it appears in all rows. But I want it to be invisible in the start. And on clicking the Edit button it should appear in all rows. I Am wondering how to achieve that.
Can someone assist me? Let me know if more code is needed.
Thanks
The problem I am facing is that when
Hi Stone i think you have to use a boolean flag. which wil determine whether the delete button should be visible or not. Try with the following example. Its working fine. On click of edit button if delete buttons are invisible i make all as visible and viceversa. Try the following code.
See My Working Example
Sample2.java
import java.util.ArrayList;
import java.util.Iterator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Sample2 extends Activity {
boolean showDeleteButtonFlag = false;
Button delteBtn2 = null;
Button delteBtn1 = null;
Button editBtn = null;
ArrayList<Button> deleteButtonList = new ArrayList<Button>();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.tablerow);
delteBtn1 = (Button) findViewById(R.id.delete1);
delteBtn2 = (Button) findViewById(R.id.delete2);
// add all delete buttons buttons to the array list
deleteButtonList.add(delteBtn1);
deleteButtonList.add(delteBtn2);
editBtn = (Button) findViewById(R.id.edit);
setVisibilityOfDeleteButtons();
editBtn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// if delete button is visible make it as invisible and viceversa
showDeleteButtonFlag = !showDeleteButtonFlag;
setVisibilityOfDeleteButtons();
}
});
}
void setVisibilityOfDeleteButtons(){
if(showDeleteButtonFlag){
Iterator<Button> itr =deleteButtonList.iterator();
while(itr.hasNext()){
itr.next().setVisibility(View.VISIBLE);
}
}else{
Iterator<Button> itr =deleteButtonList.iterator();
while(itr.hasNext()){
itr.next().setVisibility(View.INVISIBLE);
}
}
}
}
tablerow.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow>
<Button
android:id="#+id/edit"
android:layout_width="100dip"
android:layout_height="60dip"
android:text="Edit" />
<Button
android:id="#+id/delete1"
android:layout_width="100dip"
android:layout_height="60dip"
android:text="Delete" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password:"
android:textColor="#ffffff"
android:textStyle="bold" />
<Button
android:id="#+id/delete2"
android:layout_width="100dip"
android:layout_height="60dip"
android:text="Delete" />
</TableRow>
</TableLayout>

codes in onClickListener can't be executed

I'm experiencing problem with the following code, I created two buttons with onClickListener added.
It works fine for the Button -- btnAbout, I'm trying to use another way to handle btnIntro, instead of by using findViewById(...) method, but the statement will not be executed when I click btnIntro.
Why does this happen?
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class TestActivity extends Activity {
private final String TAG = "tag";
private Button btnIntro;
private Button btnAbout;
private View layoutView;
private ViewWrapper wrapper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnAbout = (Button) findViewById(R.id.btnAbout);
if (btnIntro == null) {
LayoutInflater inflator = getLayoutInflater();
layoutView = inflator.inflate(R.layout.main, null, false);
wrapper = new ViewWrapper(layoutView);
layoutView.setTag(wrapper);
} else {
wrapper = (ViewWrapper) layoutView.getTag();
}
btnIntro = wrapper.getButton();
Log.e(TAG, Integer.toHexString(layoutView.getId()) + "");
Log.e(TAG, btnIntro.getText().toString());
btnIntro.setOnClickListener(new OnClickListener() {
{
Log.e(TAG, "static");
}
#Override
public void onClick(View arg0) {
Log.e(TAG, "btnIntro clicked");
Toast.makeText(TestActivity.this, "btnIntro", Toast.LENGTH_SHORT)
.show();
}
});
btnAbout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Log.e(TAG, "btnAbout clicked");
Toast.makeText(TestActivity.this, "about", Toast.LENGTH_SHORT).show();
}
});
}
class ViewWrapper {
View base;
Button btn1;
ViewWrapper(View base) {
this.base = base;
}
Button getButton() {
if (btn1 == null) {
btn1 = (Button) base.findViewById(R.id.btnIntro);
Log.e(TAG, btn1.getText().toString());
}
return btn1;
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/MAIN_LAYOUT_XML"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="30dip">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Test" />
<Button
android:id="#+id/btnIntro"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="btnIntro" />
<Button
android:id="#+id/btnAbout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="btnAbout" />
</LinearLayout>
Problem is that you use to different content views to obtain buttons, one is created when you invoke setContentView() and second you create by invoking inflator.infate(). Thus buttons you get are placed in different content views (only one of which is shown - that created by setContentView). Try that instead:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflator = getLayoutInflater();
layoutView = inflator.inflate(R.layout.main, null, false);
setContentView(layoutView);
//..anything you need..
}

Categories

Resources