I am trying to make a dialog that consists of a LinearLayout which contains a number of other LinearLayouts that are effectively Buttons that each bring you to a website. Instead of statically making each LinearLayout Button in the layout xml file, I have a JSON feed that has a possibly changing number of buttons to display in the dialog. I found a question that looks similar...
... but I'm not sure how to dynamically add LinearLayouts to a Dialog. The data for each of the LinearLayout buttons gets parsed into an ArrayList of items, each representing a Button in the Dialog.
Normally you should use a RelativeLayout for this:
To notice, where your last created button is and to set the next one to the next position costs not so much performance as creating new layouts. You should try to call addView(); as less as possible, because each time the view must be rendered again.
But if it's necessary to add LinearLayouts, here is a sample code:
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
viewGroup.addView(linearLayout);
Use a ListView or RecyclerView and control it with an adapter.
For the dialog you can use a DialogFragment. Override the onCreateDialog method and return an AlertDialog inside. The AlertDialog.Builder has the setView method that you can use to inflate your list or recycler. Then just keep a reference to the adapter in your dialog fragment and use it to load your layout-buttons dynamically.
For example:
public class WebsitePickerDialogFragment extends DialogFragment {
Adapter adapter = new YourRecyclerViewAdapter();
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final RecyclerView contentView = LayoutInflater.from(getContext()).inflate(...
contentView.setAdapter(adapter);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(contentView);
return builder.create();
}
}
If you don't want scrolling behavior, you can still use this pattern with any adapter view, like the https://github.com/frankiesardo/LinearListView lib that uses LinearLayout like a ListView.
Related
I have a fragment to register customer addresses (called "address") that contains a "+" button.
I want to create another fragment below this containing the same content so that the customer can add as many addresses as he wants to.
I know it's possible to create components one by one programatically. But, this fragmet is a bit complex and I dont want to create it dynamically.
Is that possible to insert the same fragment several times inside a layout of the fragment itself?
I got it!
#Override
public void onClick(View v) {
LinearLayout newlayout = new LinearLayout(getContext());
newlayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
newlayout.setId(ConfigFragment.generateViewId());
LinearLayout parentlayout = (LinearLayout) view.findViewById(R.id.regpet_frame_main);
parentlayout.addView(newlayout);
ConfigFragment.openFragment(new RegPetFragment(), newlayout.getId(), getChildFragmentManager(), getString(R.string.title_reg_pet));
}
Surely new questions will come!!!
In my current spring project, one of my activities should be a form where the user can insert a new entity. the code for the activity is like this:
public class FormNewItemActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.form_new_item_view);
Intent intent = getIntent();
Dao<?> dao = intent.getStringExtra(HelloActivity.EXTRA_MESSAGE);
}
}
the layout file should have a list of EditText fields and a unique Button in the end for trigger the saving of the data in a SQLite database.
I wonder if it's possible, giving a list of string with the name of the fields of the entity class, generate a xml layout file dynamically with one EditText for each field.
Anyone knows if this is really possible and how can be done?
You cannot dynamically create and load an XML layout file. However, what you can do is dynamically create the layout programatically which will have the same effect. This method works by creating and adding views at runtime to a layout that serves as a container - such as an empty LinearLayout. In your example you would make R.layout.form_new_item_view contain an empty LinearLayout
<LinearLayout
android:id="#+id/container_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
You would then find your container layout in onCreate
LinearLayout container = (LinearLayout) findViewById(R.id.container_layout);
And then create and add TextView or EditText as you needed from a list of field names
for(String title: listOfTitles){
TextView field = new TextView(this);
field.setText(title);
container.addView(field);
}
To customize the layout further you can set LayoutParams for each view added to control margins and other parameters.
Am posting this in hopes to help someone else; but, if there is an easier way to do the same, I hope someone can share their steps. If I use the method 'setDisplayedValues' to pass an array of values to display in the NumberPicker, the underlying method forces the use of a Text Keyboard Layout, instead of the Number Layout, which isn't what I want.
I found a way to set the InputType for my NumberPicker. This is done in my extended class:
class public class NumberPickerDialogFragment extends DialogFragment:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// We are getting the parameters passed in to figure out the range of the Number Picker
NumPickerValues = getArguments().getStringArray("NumPickerRange");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View dlgNumPicker = inflater.inflate(R.layout.dialog_num_picker, null);
NumberPicker np = (NumberPicker) dlgNumPicker.findViewById(R.id.npNumberPicker);
// Always remember that NumberPicker methods need an index position, rather than the value in that array position
np.setMinValue(0);
np.setMaxValue(NumPickerValues.length-1);
np.setDisplayedValues(NumPickerValues);
np.setValue(getArguments().getInt("InitialValue"));
np.setWrapSelectorWheel(false);
np.setOnValueChangedListener(this);
// Since the underlying code for the NumberPicker sets the keyboard layout for text, due to the use of 'setDisplayedValues',
// we need to set it back to a number keyboard layout
((EditText)np.getChildAt(0)).setRawInputType(InputType.TYPE_CLASS_NUMBER);
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
return builder.setView(dlgNumPicker)
.setTitle(getArguments().getInt("NumPickerTitle"))
.setPositiveButton(getArguments().getInt("SaveButtonTitle"), new ButtonCLickListener())
.setNegativeButton(R.string.cancel, new ButtonCLickListener())
.create();
}
On the section of code above, the line that sets the InputType is
((EditText)np.getChildAt(0)).setRawInputType(InputType.TYPE_CLASS_NUMBER);
I didn't find anything on the web that does this. It seems like a clean way of doing it; but, am not sure if there is any performance issues by doing it this way. If there is, let us know.
I created an expandable listview based on this link. Its just working fine. Now what i want is
1) How to make a childview to link another sub-child view
2) The sub- child view should be open as a new list view on the window(Right side of the view) is my expected layout. I googled but couldn't find how to achieve this. Please help me in achieving this. Thanks in advance.
You'll need to specify and handle onClick event of ListView row items.
Then you'll open a new Activity, based on the item clicked.
Parameters for new activity are supplied through intent extras, the new activity can use these values to get data from cloud or process the values to show certain results.
I've used CustomAdapter class several times to handle this scenario.
class Ocl implements OnClickListener{
#Override
public void onClick(View v) {
Intent intDetail = new Intent(getActivity(), PartDetail.class);
intDetail.putExtra(_ID, mParts[position].getSPr());
intDetail.putExtra(_LOT, mParts[position].getLotID());
intDetail.putExtra(_QTY, mParts[position].getQty());
intDetail.putExtra(_UID, mParts[position].getPartID());
startActivity(intDetail);
}
}
So, do you want your first child to expand into another ListView? Or maybe just open another Activity/Fragment that contains the matching ListView?
In case you want to the the first, you could design a CustomLayout for the Childview, which on OnClick expands, and changes its content to a specific ListView.
Otherwise you would just open up another ListView with data depending on Which Child in First List was Clicked.
Well, i am using some Like that to enlarge ChildViews on Click to show me detailed information.
Im using a Class to wrap my Data named Row. These Rows indicate if they are clickable and if so, the ListView will allow clicks on the rows. A Click will then be handled by the Class itself, making the displayed Text longer(more Detailed). And in order to relayout the items, you need to call notifyDataSetChanged.
#Override
public void onClick(Context context, MyExpandableListAdapter mela) {
this.setBig(!isBig());
mela.notifyDataSetChanged();
}
So, i would handle the row state (expanded/normal) in the getView Method of parents Adapter, to decide which childLayout i inflate.
would looke something like this
public View getView (args...) {
Object data = getItem(position);
if (data.isExpanded()) {
//inflate ListView Layout, create Addapter fill it....
} else {
//show some title or whatever to identify row.
}
}
I have a activity which shows a button, a text and a list. I would like to repeat that pattern depending on data (SQLite). If I have 5 unique categories, show 5 buttons, 5 text and 5 lists. How do I do that ? How can I repeat the pattern ?
You can just add a new button text and list to the same LinearLayout. So..
addStuffz(){
LinearLayout main = (LinearLayout)findViewById(R.id.main_linearLayout);
LinearLayout newLayout = new LinearLayout(context);
/**
* Do Init here
*/
Button anotherButton = new Button(context);
/**
* Do Init here
*/
TextView anotherText = new TextView(context);
/**
* Do Init here
*/
ListView anotherList = new ListView(context);
/**
* Do Init here
*/
newLayout.addView(anotherButton);
newLayout.addView(anotherText);
newLayout.addView(anotherList);
mainLayout.addView(newLayout);
}
The standard design pattern is to use a ListActivity(or a standard activity with a listView)
and create a CursorAdapter to create views and databind values from your recordset cursor to the view.
Then call setAdapter() on your ListActvity.
VIDEO
The use of list adapters is dicussed in the Google IO 2009 video on UI improvements
in android you cannot "repeat a view" in a same actiivty (a child cannot have more than 1 parent ) but u can always do a workaround. u can write a mehod as getview() which returns u a parent view conatining ur buttons, texts etc. and u add this to the top layer viewgroup;
while(somelogic)
urparentview.addview(getview());
setcontentview(urparentview)
ur getviewmethod may be like this
view getview()
{
button b = new button(this);
edittext ed = new edittext(this);
//set orientations etc...
LinearLayout ll = new LineaLayout(this);
ll.addview(b);
ll.addView(ed);
return ll;
}