How to get text from all EditText Dynamically added in a row - android

The EditText is Dynamically added by user .
how get data from each dynamically created EditText .or get values from the dynamically created EditTexts when the user tap a save button, then store all of them , dynamically added by user and save as Share preferences or save as array thanks guys
public class ActivityOptions extends AppCompatActivity {
private LinearLayout parentLinearLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_options);
parentLinearLayout = (LinearLayout) findViewById(R.id.parent_linear_layout);
}
public void onAddField(View v) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.field, null);
// Add the new row before the add field button.
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount() - 1);
}
public void onDelete(View v) {
parentLinearLayout.removeView((View) v.getParent());
}
activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="vertical" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<EditText
android:id="#+id/edit_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:inputType="text"/>
<Button
android:id="#+id/delete_button"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="#android:drawable/ic_delete"
android:onClick="onDelete"/>
</LinearLayout>
<Button
android:id="#+id/add_field_button"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="#555"
android:layout_gravity="center"
android:onClick="onAddField"
android:textColor="#FFF"
android:text="Add Field"
android:paddingLeft="5dp"/>
<TextView
android:layout_marginTop="10dp"
android:gravity="center"
android:id="#+id/txt"
android:text="HELLO"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
fiel.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<EditText
android:id="#+id/edit_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:inputType="text"/>
<Button
android:id="#+id/delete_button"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="#android:drawable/ic_delete"
android:onClick="onDelete"/>
</LinearLayout>

You could retrieve the value by looping the parentView, something like this
ArrayList getEditTextList()
{
ArrayList<String> list = new ArrayList<String>();
int size = parentLinearLayout.getChildCount()
for (int i=0 ; i < size ; i++)
{
View view = parentLinearLayout.getChildAt(i);
EditText text = view.findViewById(R.id.yourEditTextName);
list.add(text.getText().toString());
}
return list;
}
Later you can add the values to Shared preference either by converting Arraylist to Json String or Adding it one by one.

Related

Unable to fetch correct ID from a dynamic LinearLayout table

I am trying to create a dynamic view where I will keep a button to add view to my LinearLayout. The view is getting added successfully.
I have a Spinner, and a count field with (-) (+) buttons to increase decrease the value.
ISSUE: When I am increasing the value of the 2nd or 3rd row, the 1st row value is getting increased.
Ex: If we try to increase the number of pants, the Shirt count is getting increased. And the Pant count is unchanged(0).
View from simulator for better understanding:
field.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<Spinner
android:id="#+id/type_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:entries="#array/itemTypes"
android:gravity="right"/>
<Button
android:id="#+id/decrease"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/round_button"
android:onClick="decreaseInteger"
android:text="-" />
<TextView
android:id="#+id/integer_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:textStyle="bold"/>
<Button
android:id="#+id/increase"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/round_button"
android:onClick="increaseInteger"
android:text="+"/>
</LinearLayout>
</LinearLayout>
item_quantity_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item_quantity_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="vertical" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<Spinner
android:id="#+id/type_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:entries="#array/itemTypes"
android:gravity="right"/>
<Button
android:id="#+id/decrease"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/round_button"
android:onClick="decreaseInteger"
android:text="-" />
<TextView
android:id="#+id/integer_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:textStyle="bold"/>
<Button
android:id="#+id/increase"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/round_button"
android:onClick="increaseInteger"
android:text="+"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add more item"/>
<Button
android:id="#+id/add_field_button"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/round_orange_button"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:onClick="onAddField"
android:textColor="#FFF"
android:text="+"/>
</LinearLayout>
</LinearLayout>
JavaCode
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.laundry_srf_blank);
parentLinearLayout = (LinearLayout) findViewById(R.id.item_quantity_view);
}
public void onAddField(View v) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.item, null);
// Add the new row before the add field button.
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount() - 1);
}
public void increaseInteger(View view) {
minteger = minteger + 1;
display(minteger);
}
public void decreaseInteger(View view) {
minteger = minteger - 1;
display(minteger);
}
private void display(int number) {
TextView displayInteger = (TextView) findViewById(
R.id.integer_number);
displayInteger.setText("" + number);
}
Please help!!!
Your problem is that you looking for R.id.integer_number in the root layout in private void display(int number) method and it always returns the first view what can find (in your case a Shirt field). So you need to look for R.id.integer_number locally in the current ViewGroup where was onClick() method invoked.
Refactor your code like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.laundry_srf_blank);
parentLinearLayout = (LinearLayout) findViewById(R.id.item_quantity_view);
}
public void onAddField(View v) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.item, null);
// Add the new row before the add field button.
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount() - 1);
}
public void increaseInteger(View view) {
TextView displayInteger = (TextView) view.findViewById(
R.id.integer_number);
Integer minteger = Integer.valueOf(displayInteger.getText().toString());
minteger++;
displayInteger.setText(String.valueOf(minteger));
}
public void decreaseInteger(View view) {
TextView displayInteger = (TextView) view.findViewById(
R.id.integer_number);
Integer minteger = Integer.valueOf(displayInteger.getText().toString());
minteger--;
displayInteger.setText(String.valueOf(minteger));
}

setOnClickListener on items within getView bad behavior

I am facing a really strange behaviour where I set an onClickListener on checkboxes and their labels, within a custom adapter.
The problem is when I check an answer on the first question, the same item on the 3rd question is checked too. The checkboxes seems to be synchronised, but i don't understand why.
Here is some screens to understand.
1rst question
3rd question
Here is the getView() from my adapter:
public View getView(final int position, View convertView, ViewGroup parent)
{
View vi = convertView;
if(convertView == null)
{
vi = inflater.inflate(R.layout.question_item, null);
}
Qcm qcm = qcms.get(position);
List<Proposition> propositions = qcm.getPropositionsList();
TextView numQuestion = (TextView)vi.findViewById(R.id.question_number_item);
TextView question = (TextView)vi.findViewById(R.id.question_text);
LinearLayout[] labels = new LinearLayout[5];
labels[0] = (LinearLayout)vi.findViewById(R.id.question_label1);
labels[1] = (LinearLayout)vi.findViewById(R.id.question_label2);
labels[2] = (LinearLayout)vi.findViewById(R.id.question_label3);
labels[3] = (LinearLayout)vi.findViewById(R.id.question_label4);
labels[4] = (LinearLayout)vi.findViewById(R.id.question_label5);
final CheckBox[] checkBoxes = new CheckBox[5];
checkBoxes[0] = (CheckBox)vi.findViewById(R.id.question_check1);
checkBoxes[1] = (CheckBox)vi.findViewById(R.id.question_check2);
checkBoxes[2] = (CheckBox)vi.findViewById(R.id.question_check3);
checkBoxes[3] = (CheckBox)vi.findViewById(R.id.question_check4);
checkBoxes[4] = (CheckBox)vi.findViewById(R.id.question_check5);
numQuestion.setText(String.valueOf(position+1));
question.setText(Html.fromHtml(qcm.getQuestion()));
for(int i=0; i<5; i++)
{
final int cpt = i;
checkBoxes[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Checked[i] -> !Checked[i]
QcmListAdapter.this.checked[position][cpt] = !QcmListAdapter.this.checked[position][cpt];
APIHelper.log('d', "position="+position);
// TODO : Faire la methode PlaySerieFragment.saveSession();
//QcmListAdapter.this.activity.getFragmentManager().getFragment(QcmListAdapter.this.);
}
});
labels[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkBoxes[cpt].performClick();
APIHelper.log('d', "onClick:cpt="+cpt);
}
});
Proposition p = propositions.get(i);
p.setFormattedView(this.activity, labels[i], (i + 1));
}
return vi;
}
and here is the view for an item :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/question_block"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<RelativeLayout android:id="#+id/question" android:layout_width="match_parent" android:layout_height="wrap_content">
<TextView
android:id="#+id/question_number_item"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="10dp"
android:text="X"
android:textSize="30sp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#drawable/question_number" />
<TextView
android:id="#+id/question_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:text="Question 1 : Texte descriptif de la question tellement long"
android:textSize="16sp"
android:textColor="#color/MPQ_blue"
android:layout_toRightOf="#id/question_number_item"/>
</RelativeLayout>
<RelativeLayout android:id="#+id/question_item1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="#id/question" android:layout_marginTop="16dp">
<CheckBox android:id="#+id/question_check1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="start" android:button="#drawable/play_qcm_checkbox" android:text="" android:paddingTop="13dp"/>
<LinearLayout android:orientation="vertical" android:id="#+id/question_label1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toRightOf="#id/question_check1"></LinearLayout>
</RelativeLayout>
<RelativeLayout android:id="#+id/question_item2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="#id/question_item1" android:layout_marginTop="8dp">
<CheckBox android:id="#+id/question_check2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="start" android:button="#drawable/play_qcm_checkbox" android:text="" android:paddingTop="13dp"/>
<LinearLayout android:orientation="vertical" android:id="#+id/question_label2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toRightOf="#id/question_check2"></LinearLayout>
</RelativeLayout>
<RelativeLayout android:id="#+id/question_item3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="#id/question_item2" android:layout_marginTop="8dp">
<CheckBox android:id="#+id/question_check3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="start" android:button="#drawable/play_qcm_checkbox" android:text="" android:paddingTop="13dp"/>
<LinearLayout android:orientation="vertical" android:id="#+id/question_label3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toRightOf="#id/question_check3"></LinearLayout>
</RelativeLayout>
<RelativeLayout android:id="#+id/question_item4" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="#id/question_item3" android:layout_marginTop="8dp">
<CheckBox android:id="#+id/question_check4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="start" android:button="#drawable/play_qcm_checkbox" android:text="" android:paddingTop="13dp"/>
<LinearLayout android:orientation="vertical" android:id="#+id/question_label4" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toRightOf="#id/question_check4"></LinearLayout>
</RelativeLayout>
<RelativeLayout android:id="#+id/question_item5" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="#id/question_item4" android:layout_marginTop="8dp">
<CheckBox android:id="#+id/question_check5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="start" android:button="#drawable/play_qcm_checkbox" android:text="" android:paddingTop="13dp"/>
<LinearLayout android:orientation="vertical" android:id="#+id/question_label5" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toRightOf="#id/question_check5"></LinearLayout>
</RelativeLayout>
</RelativeLayout>
I suspect this is because the view is getting re-used. Android re-uses views in a listview for performance, as the view is re-used when you click the same view displays the checked state.
You can either remove the if statement around convertView
if(convertView == null)
..
But this will be determental to performance if you have a lot of items.
Otherwise you should use the common viewHolder method:
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
Hope this helps.

Button inside ListView not clickable

I want to be able to click on a button inside an item of a ListView. It should have a different effect from clicking the whole item. I realize there are several questions asked on stackoverflow, but none of the suggestions works for me.
The ListView is inside a Fragment.
Layout of the fragment:
<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=".EventFragment" >
<ListView
android:id="#+id/event_list"
android:background="#C0FFFFFF"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp" />
</RelativeLayout>
Layout of each list item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#C0101010">
<TextView
android:id="#+id/event_list_separator"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="separator"
android:textColor="#android:color/white" />
<LinearLayout
android:id="#+id/event_list_element"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFFFF"
android:padding="6dip" >
<ImageView
android:id="#+id/event_list_element_icon"
android:layout_width="26dip"
android:layout_height="60dip"
android:layout_marginRight="6dip"
android:contentDescription="TODO" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/event_list_element_firstLine"
android:layout_width="match_parent"
android:layout_height="25dip"
android:text="item_header"
android:textSize="18sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="35dip"
android:orientation="horizontal" >
<TextView
android:id="#+id/event_list_element_secondLine"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:ellipsize="marquee"
android:singleLine="true"
android:text="Description"
android:textSize="14sp" />
<Button
android:id="#+id/event_list_element_button_1"
android:layout_width="132dip"
android:layout_height="match_parent"
android:drawableLeft="#drawable/ic_button1"
android:text="Participate"
android:textStyle="bold"
android:textSize="14sp"
/>
<Button
android:id="#+id/event_list_element_button_2"
android:layout_width="110dip"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:drawableLeft="#drawable/ic_button2"
android:singleLine="true"
android:text="No thanks"
android:textStyle="bold"
android:gravity="center_vertical"
android:textSize="14sp"
/>
<TextView
android:id="#+id/event_list_element_additional_text"
android:layout_width="100dip"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:singleLine="true"
android:gravity="center_vertical"
android:text="sample"
android:textStyle="bold"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
My list adapter is:
public class EventAdapter extends ArrayAdapter<Event> {
static class ViewHolder {
TextView separator;
LinearLayout relativeLayout;
TextView eventHeader;
TextView eventDescription;
ImageView blueDot;
Button button1;
Button button2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater)
_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.event_list_item, parent, false);
viewHolder = new ViewHolder();
viewHolder.relativeLayout = (LinearLayout) convertView.findViewById(R.id.event_list_element);
viewHolder.blueDot = (ImageView) convertView.findViewById(R.id.event_list_element_icon);
viewHolder.eventHeader = (TextView) convertView.findViewById(R.id.event_list_element_firstLine);
viewHolder.eventDescription = (TextView) convertView.findViewById(R.id.event_list_element_secondLine);
viewHolder.button1 = (Button) convertView.findViewById(R.id.event_list_element_button1);
viewHolder.button2 = (Button) convertView.findViewById(R.id.event_list_element_button2);
viewHolder.separator = (TextView) convertView.findViewById(R.id.event_list_separator);
convertView.setTag(viewHolder);
} else{
viewHolder = (ViewHolder) convertView.getTag();
}
final Event item = getItem(position);
if (item != null) {
OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(_context, "boo!", Toast.LENGTH_SHORT).show();
}
};
viewHolder.button1.setOnClickListener(listener);
}
return convertView;
}
}
The problem is that the two buttons are not clickable. What I tried to far:
ListView listView = (ListView) rootView.findViewById(R.id.event_list);
listView.setItemsCanFocus(true);
I also tried setting on the button:
android:focusable="true"
android:clickable="true"
I also experimented with android:descendantFocusability.
None of my tries made the buttons clickable.
Insert the attribute android:descendantFocusability="blocksDescendants" in the Parent Layout declaration of each list item.
The xml should be as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants"
android:background="#C0101010">
<TextView
android:id="#+id/event_list_separator"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="separator"
android:textColor="#android:color/white" />
<LinearLayout
android:id="#+id/event_list_element"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFFFF"
android:padding="6dip" >
<ImageView
android:id="#+id/event_list_element_icon"
android:layout_width="26dip"
android:layout_height="60dip"
android:layout_marginRight="6dip"
android:contentDescription="TODO" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/event_list_element_firstLine"
android:layout_width="match_parent"
android:layout_height="25dip"
android:text="item_header"
android:textSize="18sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="35dip"
android:orientation="horizontal" >
<TextView
android:id="#+id/event_list_element_secondLine"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:ellipsize="marquee"
android:singleLine="true"
android:text="Description"
android:textSize="14sp" />
<Button
android:id="#+id/event_list_element_button_1"
android:layout_width="132dip"
android:layout_height="match_parent"
android:drawableLeft="#drawable/ic_button1"
android:text="Participate"
android:textStyle="bold"
android:textSize="14sp"
/>
<Button
android:id="#+id/event_list_element_button_2"
android:layout_width="110dip"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:drawableLeft="#drawable/ic_button2"
android:singleLine="true"
android:text="No thanks"
android:textStyle="bold"
android:gravity="center_vertical"
android:textSize="14sp"
/>
<TextView
android:id="#+id/event_list_element_additional_text"
android:layout_width="100dip"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:singleLine="true"
android:gravity="center_vertical"
android:text="sample"
android:textStyle="bold"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
I found the solution! I wanted to update the list of events periodically (right now it's a thread running every x milliseconds, later I want to switch that to only update the event list when there is a change). Anyway, the code was (inside my main activity):
private BroadcastReceiver _bReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(RECEIVE_EVENT)) {
Bundle bundle = intent.getExtras();
Event event = (Event) bundle.get("event");
showEvent(event);
}
}
};
private void showEvent(final Event event){
final Context context = this;
runOnUiThread(new Runnable() {
public void run() {
final ListView listview = (ListView) findViewById(R.id.event_list);
EventAdapter adapter = new EventAdapter(context, id.event_list, getEventList());
listview.setAdapter(adapter);
}
});
}
Setting the adapter each time is certainly not the right approach. Once I changed that to only set the adapter once, it worked like suggested using android:descendantFocusability="blocksDescendants"

Dynamic View not being created in proper place. Overlapping previous view. Android

I am new to Android so I've been trying to tweak around for the past couple days but am stuck at this part. For my app, I'm trying to input a Button "Add More" which inflates a view to help incorporate user input but I'm running into issues. I looked around and I used his source code to help with my issue but I am running into the problem that my inflated xml layout is overlapping my previous set-up layout.
This is the layout that I have setup for my new_class_container file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:background="#drawable/gradient_gray">
<!-- Class Name -->
<TextView
android:id="#+id/register_class_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/write_class_name"
android:layout_marginTop="20dp"
android:layout_marginLeft="5dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#FFFFFF"/>
<EditText
android:id="#+id/register_class_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/register_class_textview"
android:layout_alignBaseline="#+id/register_class_textview"
android:inputType="text"
android:hint="#string/example_name"
android:singleLine="true" >
</EditText>
<!-- Assignment Type and Grade Weight -->
<TextView
android:id="#+id/register_assign_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/register_class_textview"
android:layout_alignLeft="#+id/register_class_textview"
android:text="#string/write_assignment_type"
android:layout_marginTop="10dp"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<EditText
android:id="#+id/register_assign_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/register_assign_textview"
android:layout_alignLeft="#+id/register_assign_textview"
android:gravity="center_horizontal"
android:hint="#string/example_assign"
android:singleLine="true">
</EditText>
<!-- Save Button -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:gravity="bottom" >
<Button
android:id="#+id/button_save"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/save_class" />
</RelativeLayout>
<Button
android:id="#+id/btnAddNewItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/register_assign_edit"
android:layout_centerHorizontal="true"
android:layout_marginTop="22dp"
android:gravity="center_horizontal"
android:onClick="onAddNewClicked"
android:paddingLeft="5dp"
android:text="#string/more_assign"
android:textColor="#FFFFFF" />
<EditText
android:id="#+id/register_weight_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/btnAddNewItem"
android:layout_alignLeft="#+id/register_weight_textview"
android:ems="10"
android:hint="#string/example_weight"
android:inputType="number"
android:singleLine="true" >
</EditText>
<TextView
android:id="#+id/register_weight_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/register_assign_textview"
android:layout_alignBottom="#+id/register_assign_textview"
android:layout_alignParentRight="true"
android:text="#string/write_assign_percent"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
This is how the layout for the code above looks like and I want to be able to press the "Add More" Button and it inflates to "create a new row", per say, of the TextViews of Assignment Type and Grade Weight and EditTexts of the respective TextViews. But when I run the app and press add more, the new set of TextView + EditText pop up right on top of what I have rather than underneath. The following is my other xml file new_class
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/register_assign_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="#string/write_assignment_type"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="#+id/register_weight_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="#string/write_assign_percent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginLeft="30dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/register_assign_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:hint="#string/example_assign"
android:singleLine="true">
</EditText>
<EditText
android:id="#+id/register_weight_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="#string/example_weight"
android:layout_marginLeft="30dp"
android:gravity="center_horizontal"
android:inputType="number"
android:singleLine="true">
</EditText>
</LinearLayout>
</LinearLayout>
And this is the Java Code that I have
public class NewClass extends Activity{
private RelativeLayout mContainerView;
private Button mAddButton;
private View mExclusiveEmptyView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_class_container);
mContainerView = (RelativeLayout) findViewById(R.id.parentView);
mAddButton = (Button) findViewById(R.id.btnAddNewItem);
}
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
//TODO: Handle Screen Rotation
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// TODO: Handle screen rotation:
// restore the saved items and inflate each one with inflateEditRow;
}
// 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());
}
private void inflateEditRow(String name) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.new_class, null);
//final ImageButton deleteButton = (ImageButton) rowView
// .findViewById(R.id.buttonDelete);
final EditText editText = (EditText) rowView
.findViewById(R.id.register_assign_edit);
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) {
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);
}
}
What can I do to prevent it from overlapping and showing up underneath? And how will I be able to move the button each time it's 'updated'? Because if I move the button to the new_class xml file then it won't show up originally for me to add more views.
I tried implementing the following code and what it did was enabled me to properly get a dynamic view added the first time but each time after it was overlapping the added view.
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
p.addRule(RelativeLayout.BELOW, R.id.register_assign_edit);
rowView.setLayoutParams(p);
This will work with having two layout files: main_layout and layout_to_include.
main_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="400dp"
android:id="#+id/sv1" >
<LinearLayout
android:id="#+id/llAddingContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include layout="#layout/layout_to_include"/>
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="#+id/llButtonHolder"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_below="#+id/sv1"
android:gravity="center_horizontal"
android:layout_above="#+id/button2" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="Add More" />
</LinearLayout>
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textAlignment="center"
android:text="Save Class" />
</RelativeLayout>
layout_to_include.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_alignParentTop="true" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Class Name:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Ex: CS 301" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="20dp"
android:layout_below="#+id/linearLayout1" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="Assignment Type"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Ex: Homework" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginRight="10dp"
android:layout_weight="1" >
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Grade Weight(%)"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/editText3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Ex: 10" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
To use these layouts in your code:
....
setContentView(R.layout.main_layout);
....
llAddingContainer = (LinearLayout) findViewById(R.id.llAddingContainer);
// Clicking on this button will add another view from 'layout_to_include' to the ScrollView
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
View view = getLayoutInflater().inflate(R.layout.layout_to_include, null);
// Find the elements in this view and set them up
EditText et1 = (EditText) view.findViewById(R.id.editText1)
....
....
....
// Add the view to the LinearLayout inside ScrollView
llAddingContainer.addView(view);
});
I'm not sure, but you can try follow code to move any view. I recommend to use RelativeLayout like your main layout.
RelativeLayout.LayoutParams bParams1 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
bParams1.leftMargin = (int) leftMrgn;
bParams1.topMargin = (int) topMgrn;
bParams1.height = (int) bHeight;
bParams1.width = (int) bWidth;
anyView.setLayoutParams(bParams1);
RelativeLayouts act like a FrameLayout if you don't give them any LayoutParams (constraints like below, above, center, etc.).
You can either construct the appropriate RelativeLayout.LayoutParams, or better yet, create an empty vertical LinearLayout in your first layout that will contain the rows. Then, just add the rows to the LinearLayout instead of the RelativeLayout.

android -> relative-layout changes button text alignment on click

This is my main.xml:`
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:addStatesFromChildren="false"
android:layout_height="wrap_content">
<TableLayout
android:id="#+id/header"
android:layout_marginRight="2dp"
android:layout_marginLeft="2dp"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:layout_width="fill_parent"
android:layout_alignParentTop="true">
<TableRow>
<TextView
android:id="#+id/leftHeader"
android:textColor="#android:color/black"
android:layout_margin="1dp"
android:gravity="center_horizontal"
android:layout_weight="1"
android:background="#ffcccccc"
android:text="textview1"
android:layout_width="30dip" />
<TextView
android:id="#+id/rightHeader"
android:textColor="#android:color/black"
android:gravity="center_horizontal"
android:layout_weight="1"
android:layout_margin="1dp"
android:background="#android:color/white"
android:text="textview2"
android:layout_width="70dip" />
</TableRow>
</TableLayout>
<ScrollView
android:id="#+id/table_scroll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="2dp"
android:layout_marginLeft="2dp"
android:layout_below="#+id/header"
android:layout_above="#+id/buttonTable">
<TableLayout
android:id="#+id/maintable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/black">
<TableRow
android:id="#+id/maintableRow">
<TextView
android:id="#+id/maintableLeft"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginRight="1dp"
android:layout_marginLeft="1dp"
android:text="textview1"
android:layout_width="30dip" />
<TextView
android:id="#+id/maintableRight"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:text="textview2"
android:layout_width="70dip" />
</TableRow>
</TableLayout>
</ScrollView>
<TableLayout
android:id="#+id/buttonTable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:layout_alignParentBottom="true">
<TableRow>
<Button
android:id="#+id/button_ResetData"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Reset Data"
android:layout_gravity="center"
android:layout_weight="1" />
<Button
android:id="#+id/button_Refresh"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Refresh"
android:gravity="center"
android:layout_weight="1" />
</TableRow>
</TableLayout>
`
After I press one of the buttons its text alignment goes to the left, how can I make it stay in center?
something similar happens with the first table (header) (textview1, textview2) but here it also reduses the textsize the amount of the text in the view...
EDIT: I managed to find the code that causes the change but I don't know how to fix this.
Maybe some one can explain me why does this happen and how to fix it?
private void fillTableView(List<BatteryInfo> list) {
TextView leftHeader = (TextView) findViewById(R.id.leftHeader);
TextView rightHeader = (TextView) findViewById(R.id.rightHeader);
LayoutParams leftHeaderLayoutParams = leftHeader.getLayoutParams();
LayoutParams rightHeaderLayoutParams = rightHeader.getLayoutParams();
TableLayout contentTable = (TableLayout) findViewById(R.id.maintable);
contentTable.removeAllViews();
for (int i = list.size() - 1; i >= 0; i--) {
TextView tv1 = new TextView(this);
tv1.setTextColor(Color.BLACK);
tv1.setGravity(Gravity.CENTER);
tv1.setBackgroundColor(Color.LTGRAY);
tv1.setLayoutParams(leftHeaderLayoutParams);
tv1.setText(String.valueOf(list.get(i).getLevel()));
TextView tv2 = new TextView(this);
tv2.setTextColor(Color.BLACK);
tv2.setGravity(Gravity.CENTER);
tv2.setBackgroundColor(Color.WHITE);
tv2.setLayoutParams(rightHeaderLayoutParams);
tv2.setText(list.get(i).getDurationTimeInString());
TableRow tblRow = new TableRow(this);
tblRow.addView(tv1);
tblRow.addView(tv2);
contentTable.addView(tblRow);
}
}
After I use removeAllViews or any addView function the layout of the top most table changes as I explained before. Why does this happen?
You can fix this by changing the android:layout_width="30dip" and android:layout_width="70dip" in leftHeader and rightHeader to android:layout_width="fill_parent". I have to admit that I'm not entirely certain why that is, though.
Instead of clearing and re-filling a TableLayout every time, though, you might want to consider using a ListAdapter. It's much more suited to what you're doing (and will probably perform better, too).
UPDATE NUMBER 2:
Notice the change in the main.xml and the change in the onCreate method. This will make your header static while letting your listview scroll, and changing from TableLayout to LinearLayout for your buttons will fix the alignment issue.
Here's how to do this with a custom adapter instead of TableLayout (which isn't really meant for dynamic data like this):
Change you main.xml to this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:addStatesFromChildren="false" android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:id="#+id/header">
<TextView android:id="#+id/leftHeader" android:textColor="#android:color/black"
android:layout_margin="1dp" android:gravity="center_horizontal"
android:layout_weight="1" android:background="#ffcccccc" android:text="textview1"
android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<TextView android:id="#+id/rightHeader" android:textColor="#android:color/black"
android:gravity="center_horizontal" android:layout_weight="1"
android:layout_margin="1dp" android:background="#android:color/white"
android:text="textview2" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:id="#+id/buttonTable" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#android:color/black"
android:layout_alignParentBottom="true" >
<Button android:id="#+id/button_ResetData"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:text="Reset Data" android:layout_gravity="center"
android:layout_weight="1" />
<Button android:id="#+id/button_Refresh"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:text="Refresh" android:gravity="center"
android:layout_weight="1" />
</LinearLayout>
<ListView android:id="#+id/listView" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_weight="1"
android:fadingEdge="none"
android:layout_below="#id/header" android:layout_above="#id/buttonTable">
</ListView>
Add XML layout files for your rows (row.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<TextView android:id="#+id/maintableLeft"
android:layout_height="wrap_content" android:layout_weight="1"
android:layout_marginRight="1dp" android:layout_marginLeft="1dp"
android:gravity="center_horizontal" android:background="#ffcccccc"
android:textColor="#android:color/black" android:layout_width="fill_parent" />
<TextView android:id="#+id/maintableRight"
android:layout_height="wrap_content" android:background="#ffcccccc"
android:textColor="#android:color/black" android:layout_weight="1"
android:layout_marginLeft="1dp" android:layout_marginRight="1dp"
android:gravity="center_horizontal" android:layout_width="fill_parent" />
</LinearLayout>
Now everything is in place to create a custom class from BaseAdapter to display your information (and make your layout work better):
class CustomAdapter extends BaseAdapter {
private List<BatteryInfo> info;
private LayoutInflater inflater;
public CustomAdapter(Context context, List<BatteryInfo> x) {
this.info = x;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return info.size();
}
public Object getItem(int position) {
return info.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v;
v = inflater.inflate(R.layout.row, parent, false);
BatteryInfo b = (BatteryInfo) getItem(position);
((TextView) v.findViewById(R.id.maintableLeft)).setText(b
.getDurationTimeInString());
((TextView) v.findViewById(R.id.maintableRight)).setText(b
.getLevel());
return v;
}
}
Modify your onCreate method to inflate the header, add it, and then bind your data to your ListView using the new CustomAdapter (I've created a fake BatteryInfo class for this example, you'll need to modify things slightly to get this working):
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ListView lv = (ListView) this.findViewById(R.id.listView);
final Context context = this;
Button refresh = (Button) this.findViewById(R.id.button_Refresh);
refresh.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
List<BatteryInfo> x = new ArrayList<BatteryInfo>();
x.add(new BatteryInfo());
x.add(new BatteryInfo());
x.add(new BatteryInfo());
x.add(new BatteryInfo());
lv.setAdapter(new CustomAdapter(context, x));
}
});
}

Categories

Resources