I am trying to create a class that creates very dynamic dialogs for my Android application.
These are examples of the dialogs I want to create:
What I need is a dynamic dialog creator. When I have a list with View objects (buttons (all with different click methods) and a title), I want to pass the list to a method that builds a dialog and shows it.
My question is: how can I make these dynamic dialogs ?
I thought of using an adapter to fill the dialogs with the view objects, but that doesn't look possible?
What do I have so far?
The code for this (not dynamic) dialog :
overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="#+id/overlay_master_view">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="#+id/linie"
android:orientation="vertical"
android:background="#drawable/tile_button_wordtile">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Menu"
android:padding="5dp"
android:textColor="#color/white"
android:background="#color/transparant"
android:layout_margin="10dp"/>
<Button
android:layout_width="wrap_content"
android:padding="5dp"
android:layout_margin="10dp"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:background="#drawable/tile_button_functiontile"
android:text="Annuleren"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
OverlayManager.java:
public static void onCoachMark(Activity c){
dialog = new Dialog(c);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setContentView(R.layout.overlay);
dialog.setCanceledOnTouchOutside(true);
//for dismissing anywhere you touch
View masterView = dialog.findViewById(R.id.overlay_master_view);
masterView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.show();
}
Extend a DialogFragment and override the onCreateView method
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.overlay, container, false);
return v;
}
and finally display it using
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
DialogFragment newFragment = new YourDialogFragment();
newFragment.show(ft, "dialog");
more info - here
Related
I have a parent layout that is used to inflate various fragments. On one such fragment layout I need to access the view elements inside the fragment class.
I'm using below code to get a reference for a text view inside the fragments layout.
CreateTaskFragment.java
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View view = getView();
endDateView = (TextView)view.findViewById(R.id.estimated_end_input);
endDateView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("Date","I'm clicked");
}
});
}
The endDateView is returning null.
fragment_create_task.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:orientation="vertical"
tools:context="com.tetrissoft.dailyplanner.CreateTaskFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/estimated_end_date"
android:textSize="15sp"
android:layout_marginTop="10dp"
android:layout_marginLeft="15dp"
android:id="#+id/estimated_end_label"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/task_end_date_input"
android:textSize="18sp"
android:inputType="date"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_below="#+id/estimated_end_input"/>
</LinearLayout>
MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/drawer_layout">
<!-- The Main Content Layout -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="25dp"
app:elevation="4dp"
android:clickable="true"
android:src="#drawable/ic_create_black_24dp"
android:id="#+id/fab_button"/>
</FrameLayout>
<!-- The Navigation Drawer-->
<ListView
...
</ListView>
</android.support.v4.widget.DrawerLayout>
How can I get the reference to the view elements of CreateTaskFragment?
Copy below method in your fragment and remove your onActivityCreated method from fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_create_task, container, false);
TextView endDateView = (TextView)rootView .findViewById(R.id.estimated_end_input);
endDateView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("Date","I'm clicked");
}
});
return rootView;
}
I'm new to android developing...
I've created a listview using Strings and Array Adapter in setting.java:
public class setting extends Activity {
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setting_layout);
String[] settingOptions = new String[]{getString(R.string.settingInterface), getString(R.string.settingLanguages), getString(R.string.settingInfo)};
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this, android.R.layout.simple_list_item_1, android.R.id.text1, settingOptions);
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
}
and this is my setting_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
setting_layout Activity(listView)
I want to create a popup menu for Languages item that when I click on it,shows some other languages translations.
I've created a string.xml in other languages but I don't know how to use it in popup menu.
1:How can I make a popup menu shown when I click on Languages item?
2:How to put other languages in popup menu?
Thanks in advance
for pop up you can create a dialog using dialog builder, it can be a custom one(xml layout), or can be created dynamically (programmatically using java)
check out this code for a pop up view :)
for example I have this function that I call inside the onClick:
private void showFlavorDialog(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
View promptView;
LayoutInflater layoutInflater = LayoutInflater.from(myActivity.this); //this gets the custom layout inflater
promptView = layoutInflater.inflate(R.layout.dialog_flavors_ar, null); // here you put the custom xml leyout name
final EditText editText = (EditText) promptView.findViewById(R.id.editText_note); //my layout has an edit text and button in it and I want to use it, so call the findviewbyid
Button add_note = (Button) promptView.findViewById(R.id.button_note);
editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); //this removes full screen keyboard, so the keyboard doesnt take the whole screen.
add_note.setOnClickListener(new View.OnClickListener() { //onClick for the button
#Override
public void onClick(View v) {
otherNote_b = true;
flavor = editText.getText().toString();
new httpSetFlavor().execute();
alertDialogFL.cancel();
}
});
if (selectedflavorNameEn.size() > 1) {
flavorsGrid = (GridView) promptView.findViewById(R.id.gridView_flavors); // I also have a gridview in the layout
flavorsGridAdapter adapter = new flavorsGridAdapter(OrderActivityAr.this,
selectedflavorNameEn);
flavorsGrid.setAdapter(adapter); // this is a custom adapter for the grid which you wont need
}
alertDialogBuilder.setTitle(R.string.flavor_ar); //title of the popup window
alertDialogBuilder.setView(promptView); //set view of the popup to your custom view
alertDialogBuilder.setCancelable(true); //this makes the popup cancelable on back button pressed
alertDialogBuilder.setPositiveButton(R.string.delete_flavor_ar, new DialogInterface.OnClickListener() { //this is a button for the popup if you want one
public void onClick(DialogInterface dialog, int id) {
deleteFlavor = true;
new httpSetFlavor().execute();
}
});
alertDialogBuilder.setNegativeButton(R.string.back_ar, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialogFL = alertDialogBuilder.create(); //here you create the dialog using its builder
alertDialogFL.show(); // show it on screen
}
and this is my custom layout xml file, so you can just put any layout you want in it and use it later :)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<GridView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:id="#+id/gridView_flavors"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:numColumns="3"
android:horizontalSpacing="2dp"
android:verticalSpacing="2dp" />
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/gridView_flavors"
android:layout_marginTop="5dp">
<Button
style="?android:attr/buttonStyleSmall"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:singleLine="true"
android:layout_height="wrap_content"
android:text="#string/add_note_ar"
android:id="#+id/button_note"
android:layout_below="#+id/gridView_flavors"
android:textSize="20dp"
android:background="#drawable/button_plain_green"
android:textColor="#000"
android:layout_weight="0" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText_note"
android:layout_below="#+id/gridView_flavors"
android:layout_toRightOf="#+id/other_text"
android:layout_marginTop="2dp"
android:layout_toLeftOf="#+id/button_note"
android:layout_toStartOf="#+id/button_note"
android:layout_weight="1"
android:gravity="right" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="#string/other_note_ar"
android:id="#+id/other_text"
android:layout_below="#+id/gridView_flavors"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignBottom="#+id/editText_note"
android:gravity="center"
android:textSize="20dp"
android:layout_weight="0"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" />
<com.andexert.library.RippleView
android:layout_width="wrap_content"
android:id="#+id/ripple_button"
android:layout_weight="0"
android:layout_height="wrap_content"></com.andexert.library.RippleView>
</TableRow>
</RelativeLayout>
this is the look of the layout:
and in your case you can use listview in the custom layout as well :) but with custom list item for example a radio button.
as for displaying other languages saved in xml
well you should have them saved in res/strings.xml
you can use the strings in an array of strings like this:
String strArray[]={
getResources().getString(R.string.string1),
getResources().getString(R.string.string2),
getResources().getString(R.string.string3),
getResources().getString(R.string.string4)
};
IF the ListView has a lot of children and she needs to scroll i can't see the dismiss button at the end of the FragmentDialog.
Here you can see the Dismiss Button:
And in the long ListView you can't see at the bottom the Dismiss Button:
dialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/dialog_header_text_view_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/dialog_header_text_view_text"
android:textSize="22sp"
android:textColor="#color/opening_words_dialog_header_color"
android:layout_marginBottom="15sp"
android:textStyle="bold"
/>
<ListView
android:id="#+id/dialog_list_view_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/dialog_header_text_view_id"
/>
<Button
android:id="#+id/dialog_dismiss_button_id"
android:layout_width="100sp"
android:layout_height="50sp"
android:text="#string/list_view_button_footer_text"
android:layout_below="#+id/dialog_list_view_id"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
CustomDialogFragment.java:
public class CustomDialogFragmentYearsKnownLoveMails extends DialogFragment
{
TextView listViewItemTextView;
ArrayAdapter<String> arrayAdapter;
ListView dialogListView;
String[] items = new String[120];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.dialog, container,false);
setCancelable(false);
listViewItemTextView = (TextView) rootView.findViewById(R.id.list_view_item_text_view_id);
dialogListView = (ListView) rootView.findViewById(R.id.dialog_list_view_id);
dissmissDialogButton = (Button) rootView.findViewById(R.id.dialog_dismiss_button_id);
for (int i = 0;i < items.length;i++)
{
items[i] = "" + (i + 1);
}
arrayAdapter = new ArrayAdapter<String>(LoveMailsActivity.this, R.layout.list_view_row,R.id.row_text_view_id,items);
dialogListView.setAdapter(arrayAdapter);
dialogListView.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
Toast.makeText(getActivity(), items[position], Toast.LENGTH_SHORT).show();
loveEmailYearsKnownTextView.setText(items[position]);
}
});
dissmissDialogButton.setOnClickListener(new View.OnClickListener() // Dismiss button click
{
#Override
public void onClick(View v)
{
dismiss();
}
});
return rootView;
}
}
So what's wrong with it?
if you need any more info just ask.
The list view, by the constraints above and below, is "stretch" from the bottom (i.e. base line) of the text view to the top of the button. Usually I start to write the component which touch the parent view (i.e. align parent top/bottom) and finish with the view in the middle as this view list.
The trick is to expand the list below the textview and above the button like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/dialog_header_text_view_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/dialog_header_text_view_text"
android:textSize="22sp"
android:textColor="#color/opening_words_dialog_header_color"
android:layout_marginBottom="15sp"
android:textStyle="bold"
/>
<Button
android:id="#+id/dialog_dismiss_button_id"
android:layout_width="100sp"
android:layout_height="50sp"
android:text="#string/list_view_button_footer_text"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
<ListView
android:id="#+id/dialog_list_view_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/dialog_header_text_view_id"
android:layout_above="#id/dialog_dismiss_button_id"
/>
</RelativeLayout>
For listview in XML change attribute layout_below to layout_above ="#id/dialog_dismiss_button_id"
And remove layout_below attribute from Button. And Add this to button
android:layout_alignParentBottom="true"
Hope this helps you :)
so I know there are a few topics around here that ask about this but none seemed to be the cause of my issue. I have an ActionBarActivity that is going to be switching between a few different fragments, but I'm having a problem getting one of the fragments to show up. The activity does show a fragment when it is first loaded and does that fine. Here is the code that is setting up the initial fragment with the method to switch between fragments that I'm using.
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
final ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("");
if (savedInstanceState == null) navigateTo(START_SCREEN);
}
public void navigateTo(int sectionNumber, Serializable objectParam) {
Fragment fragment = null;
switch (sectionNumber) {
case START_SCREEN:
fragment = createStartScreenFragment(); //returns an instance of the class for this fragment
break;
case SCREEN_TWO:
fragment = createSecondScreenFragment(); //returns an instance of the class for this fragment
break;
}
if (fragment == null) return;
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction trans = fm.beginTransaction();
trans.add(R.id.activity_container, fragment, fragment.getTag());
trans.commit();
trans.show(fragment);
}
activity_containers.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:id="#+id/activity_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
The first fragment that loads successfuly
<GridLayout
android:id="#+id/fragment_start_screen"
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"
tools:context="com.android.Activity">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
/>
...
</GridLayout>
And here is the fragment xml that isn't showing up
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
And here is the misbehaving fragments relevant code:
public class SecondFragment extends Fragment {
public final static int SECTION_NUMBER = 1;
private String mTag = "TAG";
private ParentActivity parentActivity;
public SecondFragment() {
}
public static fragment newInstance() {
SecondFragment fragment = new SecondFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(final Activity activity) {
super.onAttach(activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
parentActivity = (ParentActivity) getActivity();
View rootView = inflater.inflate(R.layout.fragment_second_fragment, container, false);
ListView list = (ListView) rootView.findViewById(R.id.list);
return super.onCreateView(inflater, container, savedInstanceState);
}
}
The biggest problem I'm having here is that there is no error message shown. The text view in the first fragment is supposed to trigger the second fragment to show up on the screen. This used to work when I had that fragment as a DialogFragment and just called .show() on an instance of it. I need it to be a regular fragment now and it doesn't show up. There's no error message that I can see, though debugging it does show it running through all of my code successfully and it looks like its properly inflating the view.
So what could I be missing here that is preventing the fragment from displaying?
Your layout
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
Should be within a ViewGroup
<?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">
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
</LinearLayout>
And you should return rootView in onCreateView().
Also, you might need to use replace method of Fragment Manager to replace one fragment with another, instead of add.
I have some fragments that are being added programatically with differing tags. Each holds a button with an xml onClick that gets passed a view. How do I identify which fragment was clicked from that view? Code is below.
NewFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.new_fragment, container, false);
TextView tv = (TextView) view.findViewById(R.id.name);
Bundle bundle = this.getArguments();
int index = bundle.getInt("index");
tv.setText(Integer.toString(index));
return view;
}
Activity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
for (int loop = 0; loop < 4; loop++) {
NewFragment fragment = new NewFragment();
Bundle args = new Bundle();
args.putInt("index", loop);
fragment.setArguments(args);
//tag set to value of loop here
ft.add(R.id.new_fragment, fragment, Integer.toString(loop));
}
ft.commit();
}
public void toggleEdit(View view) {
//How do I find clicked fragment?
}
new_fragment.xml
<?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="wrap_content"
android:id="#+id/test">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:layout_marginLeft="5dp"
android:padding="5dp"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/name"
android:text="Test"
/>
</LinearLayout>
<!-- Button in question is below -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="#string/edit"
android:onClick="toggleEdit"
android:id="#+id/edit_button"
/>
</LinearLayout>
Have your Fragment define an interface which your activity implements. Give that interface a method with a string parameter, and onClick, pass in the current Fragment's tag.
See this guide on Fragment communication for more detail http://developer.android.com/training/basics/fragments/communicating.html