I have a xml file: row.xml which contains a EditText (et) and a Spinner.
The activity starts, I "inflate" row.xml in a View and I set a listener that - when et changes, a row.xml is automatically inflated.My code is like below.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="3dp"
android:paddingBottom="3dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/spinnerDay"
android:id="#+id/nameUser"
android:theme="#style/myEditText"
android:layout_marginRight="18dp"
/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="38dp"
android:id="#+id/spinnerDay"
android:layout_alignParentRight="true"
android:popupBackground="#FFFFFFFF"
android:background="#drawable/selector_spinner">
</Spinner>
</RelativeLayout>
My problem is to set a listener for the new row in order to repeat the trick.
LinearLayout v = new LinearLayout(context);
v.addView(rowView);
View rowView = inflater.inflate(R.layout.row, null);
((LinearLayout) rootView.findViewById(R.id.userList)).addView(v);
R.id.userList is the View where I inflate row.xml
Listener for EditText
((EditText) rootView.findViewById(R.id.nameUser)).setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
LinearLayout v = new LinearLayout(view.getContext());
v.addView(rowView);
((LinearLayout) rootView.findViewById(R.id.userList)).addView(v);
return false;
}
});
I am not an expert programmer so I do ask: what is the best way to a product such an effect and retry the data inserted?
Everything is made more tricky because I am working in Fragments in a FragmentActivity and I am supposed to get the data in the last one, before confirm...how can I save the et's content?
Any help will be appreciated, thank you!
Related
I have a listview which occupies all the space of the layout IN THEORY, but actually it occupies only half of the layout because it has got only 5 elements and it doesn't cover all the screen. I'd like to know when I touch OUTSIDE of the listview. I tried to create a clicklistener method for the layout of the listfragment which contains the list, but it is never used because IN THEORY the listview occupies all the layout, so the click isn't found. It is the same for the layout of the activity more or less. In that case the click is found only on the edges, so I can't find a method to solve my problem.
Here is the fragment layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list" />
Here is the activity layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.utente.actionbar.MainActivity">
<Button
android:text="MULTI"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="26dp"
android:id="#+id/button" />
<Button
android:text="SINGOLO"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/button"
android:layout_alignLeft="#+id/button"
android:layout_alignStart="#+id/button"
android:layout_marginBottom="25dp"
android:id="#+id/button2" />
IN THEORY the listview occupies all the layout
Not a theory, that is exactly what happens; by using android:layout_height="match_parent" the View will always take the full screen height.
listView.setOnClickListener would work if you want to see if you clicked anywhere in the ListView, but you typically would instead want listView.setOnItemClickListener to see if you have clicked on any single item, and not the entire list.
Refer: difference between onClickListener and onItemClickListener
If you really want to shrink the ListView, then android:layout_height="wrap_content" is an option, but I'm not sure that works without content actually being loaded into that View since the content wrapping is applied at inflation-time, which since it has no adapter set, can't be done.
If you are needing to detect a listener literally "outside the ListView", then you need to set some type of click / touch listener on the rootView of that Fragment.
public View onCreateView(...) {
rootView = inflater.inflate(...);
listView = ...;
listView.setOnTouchListner(...
#Override
public boolean onTouch(View v, MotionEvent event) {
return false; // Says that click was not handled here.
}
});
rootView.setOnTouchListner(...
// TODO: Check if click landed outside the ListView
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() != android.R.id.listView) { // Not the list
if (event.getAction() == MotionEvent.ACTION_UP) {
// Up action more reliable than "down"
return true;
}
}
}
);
return rootView;
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content" <!-- Or specific height -->
android:id="#android:id/list" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/clickView" />
</LinearLayout>
In Fragmet
public View onCreateView(...) {
rootView = inflater.inflate(...);
View clickView = rootView.findViewById(...);
clickView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do something here
}
});
return rootView;
}
I guess this solves your problem.
I've tried a lot of other answers on SO, none of them seem to work for me. I'm not sure what I did wrong.
Here's my xml:
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/product_category_spinner"
android:theme="#style/AppartmentBlue" />
And here's my Java (it's a DialogFragment extending class):
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_product_dialog, container, false);
Spinner productCategory = (Spinner) v.findViewById(R.id.product_category_spinner);
ArrayAdapter<String> spinnerAdapter =
new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.category_array));
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
productCategory.setAdapter(spinnerAdapter);
// setCancelable(false);
return v;
}
The thing is, the text is white on very bright gray. It came that way by default, if it came in black foreground I wouldn't need to touch it. Why's it doing this? My theme extends from Theme.Holo.Light.DarkActionBar.
I don't wanna set it at runtime, I'm gonna have a lot of spinners and I want it to be global across the app, with the option for me to add later themes.
I hope this helps:
My Spinner:
<Spinner
android:id="#+id/spinner_cat"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginStart="#dimen/left_margin_large"
android:layout_marginLeft="#dimen/left_margin_large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"/>
Setting up the adapters:
private final int _singleItemRes = R.layout.simple_spinner_item;
private final int _dropdownRes = R.layout.simple_spinner_dropdown_item;
ArrayAdapter<String> adapter = new ArrayAdapter<String>(_handler.getContext(), _singleItemRes, getTitles());
adapter.setDropDownViewResource(_dropdownRes);
simple_spinner_item.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="#color/actionbar_text"
android:textSize="20sp"
android:textStyle="normal"/>
simple_spinner_dropdown_item.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#color/primary_dark"
android:ellipsize="marquee"
android:layout_centerVertical="true"
android:singleLine="true"
android:paddingRight="#dimen/left_margin_small"
android:paddingLeft="#dimen/left_margin_small"
android:textColor="#color/actionbar_text"/>
Let me know if I am missing anything from the answer and I will add it in.
I've made the next layout xml code which I call it layout_one -
<?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"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/layout_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:layout_marginTop="50dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:text="Testing 1"
android:textSize="20sp" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/info_layout"
android:visibility="gone">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
As you can see there are two layout in it - one with textview and button and one with textview.
The layout with the only textview - is gone, And i want by a click on the button, from the visible layout, it will be shown.
Now at the activity i wrote the next code -
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
ScrollView sv = new ScrollView(this);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
sv.addView(ll);
LinearLayout newView0 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
LinearLayout newView1 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
LinearLayout newView2 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
LinearLayout newView3 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
ll.addView(newView0);
ll.addView(newView1);
ll.addView(newView2);
ll.addView(newView3);
setContentView(sv);
newView1.findViewById(R.id.layout_one).setBackgroundColor(0xff0000ff);
TextView tv3 = (TextView) newView3.findViewById(R.id.textView1);
tv3.setText("Suprise Suprise");
infoLay = (View) findViewById(R.id.info_layout);
ll.addView(newView3);
}
Now there is something I don't understad - How could I set an on click listener to the button that will know which layout to show?
Tanks for any kind of help
Actually, there are three linear layouts, which seems redundant.
You can set the onclick listener by checking if textview of each layout is empty or not.
First off, have a look at this http://developer.android.com/training/improving-layouts/reusing-layouts.html. Use that <include> tag instead of dynamically creating all these layouts in your Activity class. Define your ScrollView, and all your LinearLayouts in your test_layout.xml file.
Then, in your Activity, all you have to do is get a reference to those views that's you've defined using findViewById.
Once you've got that working we can address your question as follows:
setContentView(R.layout.test_layout);
LinearLayout layout1 = (LinearLayout)findViewById(R.id.layout1);
LinearLayout layout2 = (LinearLayout)findViewById(R.id.layout2);
LinearLayout layout3 = (LinearLayout)findViewById(R.id.layout3);
OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View view) {
((View)view.getParent().getParent()).findViewById(R.id.textView2).setVisibility(View.VISIBLE);
}
});
layout1.findViewById(R.id.button1).setOnClickListener(listener);
layout2.findViewById(R.id.button1).setOnClickListener(listener);
layout3.findViewById(R.id.button1).setOnClickListener(listener);
I'd also add that it seems like you're trying to create a list here, in which case you should use a ListView instead of many LinearLayouts.
I have layout with controls:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contact_phones_layout_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/contact_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:inputType="phone" />
<Spinner
android:id="#+id/contact_phone_type"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
And I want to inflate it into another layout on the fragment. Quantity of these controls depends on values in a array. Array contains controls objects. So every time onCreateView rises I filled the layout from the array:
private void addLine(PhoneLine line) {
LinearLayout layout = (LinearLayout) mLayout.findViewById(R.id.contact_phones_layout);
View view = line.getParent();
((ViewGroup) view.getParent()).removeView(view);
layout.addView(view, layout.getChildCount() - 1);
setButtonVisible(false);
}
if line is null controls are created this way:
private void addLine() {
LinearLayout layout = (LinearLayout) mLayout.findViewById(R.id.contact_phones_layout);
View view = inflater.inflate(R.layout.contact_phone_line, layout, false);
EditText phoneEditText = (EditText) view.findViewById(R.id.contact_phone);
Spinner phoneType = (Spinner) view.findViewById(R.id.contact_phone_type);
phoneLines.add(new PhoneLine(phoneEditText, phoneType, view));
layout.addView(view, layout.getChildCount() - 1);
}
But after that I get same values in all EditText/Spinner controls, values equal to last element in the array. What can be wrong? May be there is more pure way to add controls dynamically?
I fixed it by adding controls when onResume rises, not onCreateView. But I still don't understand why onCreateView changes all values.
I have read about problems that onClickListener will consume onItemClickListener Events like here or here. My Problem is exactly the other way:
I have a CustomAdapter extends ArrayAdapter where I place model Objects to generate a row. In My Activity i registered an onItemClickListener like so
//items can focus false to try to get the onItemClick-event
mListView.setItemsCanFocus(false);
mListView.setOnItemClickListener(this);
mListView.setAdapter(this.favoritePointAdapter);
then in my Adapter.getView() Method I inflate my layout get my ImageView and register an OnClickListener on it like this
#Override
public View getView(int position, View convertView, ViewGroup parent){
//....inflate other Views.....
LinearLayout clickArea = (LinearLayout)convertView.findViewById(R.id.list_row_favorite_point_click_area);
clickArea.setOnClickListener(this);
//... other logic follows ...
}
at least i Try to fetch this Events in my Adapter like this
#Override
public void onClick(View v) {
Log.d("ListAdapter", "onClick triggered");
//never triggered
switch (v.getId()) {
case R.id.list_row_favorite_point_click_area:
Log.d("ListAdapter", "onClick id->list_row_favorite_point_click_area");
//never triggered
break;
default:
break;
}
}
If you find xml of RowView interesting, here it is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_row_relative_parent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="false">
<LinearLayout
android:id="#+id/list_row_icon"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_gravity="center_vertical"
android:layout_margin="3dip"
/>
<LinearLayout
android:layout_weight="50"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical">
<TextView
android:id="#+id/list_row_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#333333"
android:text="defaultText"
android:textStyle="bold" />
<TextView
android:id="#+id/list_row_region"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#999999"
android:textStyle="italic"
android:text="Region" />
</LinearLayout>
<LinearLayout
android:id="#+id/list_row_favorite_point_click_area"
android:layout_width="50dip"
android:layout_height="50dip">
<ImageView
android:id="#+id/list_row_favorite_icon"
android:layout_width="20dip"
android:layout_height="20dip"
android:layout_gravity="center_vertical"
android:layout_weight="0.1">
</ImageView>
</LinearLayout>
</LinearLayout>
As I said, The ListView's onItemClick of My Activity gets triggered while I never reach onClick inside my Adapter. I think that onItemClick 'feels' responsible for the whole row and consumes TouchEvents. What can I do to work around it?
Note: I tried setItemsCanFocus(false) and focusable in my root to false, too, as mentioned in the other questions.
Rather than using an onClickListener, I'd suggest using the onTouchListener.
Check out this tutorial, which I have used before to get the "swipe screens" in an application:
http://www.warriorpoint.com/blog/2009/05/29/android-switching-screens-by-dragging-over-the-touch-screen/
Also, see the android dev docs on the onTouchListener:
http://developer.android.com/reference/android/view/View.OnTouchListener.html