I am using builder to create AlertDialogs in Android using the pattern:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(...);
builder.setMessage(...);
builder.setPositiveButton(button1Text, ...);
builder.setNeutralButton(button2Text, ...);
builder.setNegativeButton(button3Text, ...);
builder.show();
Currently, only two of the buttons are displayed, because the buttons are too wide to fit in the dialog. How can I enforce the buttons to stack vertically?
I am using the Theme.AppCompat.Dialog.Alert theme, which uses ButtonBarLayout to build the buttons. According to this answer, ButtonBarLayout can stack wide buttons vertically automatically, when its mAllowStacking property is set, but it seems to default to false in my case. Is there a way I can set it to true when I build the AlertDialog?
I don't prefer hacks. But this strikes me immediately.
If the button text it too long to all fit horizontally, then it will
automatically get laid out in a vertical column of three buttons.
Just make the button text long.
builder.setPositiveButton(" Yes", { dialog, _ -> {} })
builder.setNeutralButton(" May be", { dialog, _ -> {} })
builder.setNegativeButton(" No", { dialog, _ -> {} })
You can't do that with an AlertDialog . You should create a custom Dialog, and implement that yourself. Something like this would do it
Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.dialog_layout);
dialog.setTitle(...);
dialog.setMessage(...);
dialog.show();
and your layout dialog_layout.xml should be something like
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
orientation="vertical">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
What if you did the alert box as a list?
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.pick_color)
.setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
}
});
return builder.create();
}
Example taken from here (under adding a list): https://developer.android.com/guide/topics/ui/dialogs.html
Then just take those list options and turn them into what you want.
This is a problem with MaterialAlertDialog as well.
I tried many solutions, but I think the best one is to override the button layout that material dialogs use. Copy paste the content of mtrl_alert_dialog_actions.xml from the material library and do the necessary changes. For example change the ButtonBarLayout to a LinearLayout with vertical orientation.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/buttonPanel"
style="?attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollIndicators="top|bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingTop="2dp"
android:paddingBottom="2dp">
<Button
android:id="#android:id/button1"
style="?attr/buttonBarPositiveButtonStyle"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_height="wrap_content"/>
<Button
android:id="#android:id/button2"
style="?attr/buttonBarNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_height="wrap_content"/>
<Button
android:id="#android:id/button3"
style="?attr/buttonBarNeutralButtonStyle"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
Then override the layout by adding it to res/values/refs.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<item name="mtrl_alert_dialog_actions" type="layout" tools:override="true">#layout/mtrl_alert_dialog_actions_custom</item>
</resources>
Related
I have a material alert dialog box like this:
Here is the java code for the dialog box:
public void openAddNoteDialog() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(MainActivity.this, R.style.dialogBoxTheme);
builder.setTitle("Add note");
builder.setBackground(getResources().getDrawable(R.drawable.dialog_box, null));
builder.setIcon(R.drawable.ic_add_note);
builder.setView(R.layout.addnote_dialog);
builder.setPositiveButton("Add", ((dialogInterface, i) -> handleAddNote()));
builder.setNegativeButton("Cancel", (dialogInterface, i) -> dialogInterface.dismiss());
builder.show();
}
And here is the layout that is in the dialog box:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/notenameFLD"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="260dp"
android:layout_height="90dp"
android:layout_gravity="center"
android:layout_marginTop="25dp"
android:hint="#string/notename"
android:textColorHint="#color/white"
app:boxStrokeColor="#color/white"
app:counterEnabled="true"
app:counterMaxLength="20"
app:counterTextColor="#color/white"
app:helperTextTextColor="#color/white"
app:hintTextColor="#color/white">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/notenameEDITFLD"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/opensans_regular"
android:maxLength="20"
android:textColor="#color/white"
android:textSize="20sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/notecontentFLD"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="260dp"
android:layout_height="90dp"
android:layout_gravity="center"
android:layout_marginBottom="25dp"
android:hint="#string/notecontent"
android:textColorHint="#color/white"
app:boxStrokeColor="#color/white"
app:counterEnabled="true"
app:counterMaxLength="250"
app:counterTextColor="#color/white"
app:helperTextTextColor="#color/white"
app:hintTextColor="#color/white">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/notecontentEDITFLD"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/opensans_regular"
android:maxLength="250"
android:textColor="#color/white"
android:textSize="20sp" />
</com.google.android.material.textfield.TextInputLayout>
Now, I'm trying to get the value of these input fields in other function called handleAddNote().
final TextInputEditText noteNameFLD = findViewById(R.id.notenameEDITFLD);
final TextInputEditText noteContentFLD = findViewById(R.id.notecontentEDITFLD);
The problem is, when I'm trying to get the values of these input fields as strings, they return nothing. What is the problem here? Is this because the findViewById() can't find the fields as they are inside of the alert dialog box and not in the actual activity?
Ps. sorry if this is confusing, I can add more info if needed.
Is this because the findViewById() can't find the fields as they are
inside of the alert dialog box and not in the actual activity?
Yes, you are correct :) you need to get them on the view you set to your dialogBuilder. Change the way you set your dialog view to:
final View dialogView = LayoutInflater.from(context).inflate(R.layout. addnote_dialog, null);
alertDialogBuilder.setView(dialogView);
Then, you can find the views using dialogView.findViewById().
I used youtuber Coding in Flow's method to create a custom dialog. I've been trying all day to make the dialog's background transparent. I've used every single method I've found online. Non worked.
Here's how it goes:
First here's the Dialog layout layout_dialog.xml :
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:background="#drawable/dialog_background">
<!-- The contents of the Dialog go here -->
</RelativeLayout>
<ImageView
android:id="#+id/iconImageView2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:background="?attr/actionBarItemBackground"
android:scaleType="fitCenter"
app:srcCompat="#android:mipmap/sym_def_app_icon" />
</RelativeLayout>
Here's the Dialog class:
public class DialogBrightness extends AppCompatDialogFragment {
//declare whatever variables here
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.layout_dialog, null);
builder.setView(view)
.setTitle("Login")
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//get whatever values
listener.apply(//values);
}
});
//findViewById for your dialog contents here
return builder.create();
}
public interface DialogBrightnessListener {
void apply(//values);
}
}
And here's the Dialog being called from the Main activity:
DialogBrightness dialogBrightness = new DialogBrightness();
dialogBrightness.show(getSupportFragmentManager(), "Brightness Dialog");
This is how the Dialog appears:
I'm trying to make the top white part invisible. Nothing works!
Try this:
put the code below in the onCreateDialog:
// set the dialog background to transparent
getDialog().getWindow().setBackgroundDrawable(newColorDrawable(Color.TRANSPARENT));
// remove background dim
getDialog().getWindow().setDimAmount(0);
You can design the layout like following. There is an extra layout, but in case of dialogs, it will help
Try this:
set the background color of the parent layout to:
android:background="#android:color/transparent"
like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:background="#drawable/dialog_background">
<!-- The contents of the Dialog go here -->
</RelativeLayout>
<ImageView
android:id="#+id/iconImageView2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:background="?attr/actionBarItemBackground"
android:scaleType="fitCenter"
app:srcCompat="#android:mipmap/sym_def_app_icon" />
</RelativeLayout>
Hi Im posting this after not finding any possible answer here.
I have an invisible LinearLayout LL1 in a fragment that I turn visible when a recylerView data is empty, that LL1 has a button on it. The problem is simply that the button is not clickable ! I tried setting the listener in different ways but still not working. Here's the code below:
Here's the xml file:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.main.MainActivity"
android:layout_marginTop="3dp">
<LinearLayout
android:id="#+id/msg_emty_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
android:orientation="vertical">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/ic_empty_box" />
<TextView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Aucune vente n'a été trouvée !"
android:textSize="15dp"
android:layout_gravity="center_horizontal"
android:textColor="#color/greydark"/>
<Button
android:id="#+id/btnAddSale"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Créer une vente"
android:textColor="#color/whiteTextColor"
android:background="#drawable/centre_button">
</Button>
</LinearLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_db"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_sale_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_add_db"
android:layout_margin="20dp"
android:layout_gravity="bottom|end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorAccesGreen"
android:src="#drawable/ic_edit"/>
</android.support.design.widget.CoordinatorLayout>
And here's the java:
private void generateSaleList(ArrayList<Sale> saleArrayList, View view) {
if(saleArrayList.isEmpty()){
getActivity().setTitle("Ventes sur portable");
msgLayout.setVisibility(View.VISIBLE);
creatSaleBtn = (Button) view.findViewById(R.id.btnAddSale);
creatSaleBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Button clicked !", Toast.LENGTH_LONG).show();
}
});
creatSaleBtn.setClickable(true);
}else{
msgLayout.setVisibility(View.GONE);
recyclerView_db = view.findViewById(R.id.recycler_view_sale_list);
adapter_db = new SaleAdapter((ArrayList<Sale>) Utils.sortArray(saleArrayList),this,1,getContext(),this);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView_db.setLayoutManager(layoutManager);
recyclerView_db.setAdapter(adapter_db);
adapter_db.notifyDataSetChanged();
}
}
Do you guys see what's causing this weird problem ?
You can try with requestFocusFromTouch()
Call this to try to give focus to a specific view or to one of its
descendants.
msgLayout.setVisibility(View.VISIBLE);
creatSaleBtn = (Button) view.findViewById(R.id.btnAddSale);
creatSaleBtn.requestFocusFromTouch();
Hide your RecyclerView when there's no items (set visibility to gone). The problem is that it's capturing the clicks, since it's placed on top of the button.
as u said in comments you not using creatSaleBtn.setClickable(false); anywhere, then you have to hide the recyclerView using recyclerView_db.setVisibility(View.GONE);
why? because it by default fits the full-screen due too match_parent for width and height.
please add recyclerView_db.setVisibility(View.GONE); in the saleArrayList.isEmpty() check
so your new code will be :
if(saleArrayList.isEmpty()){
recyclerView_db.setVisibility(View.GONE);
getActivity().setTitle("Ventes sur portable");
msgLayout.setVisibility(View.VISIBLE);
creatSaleBtn = (Button) view.findViewById(R.id.btnAddSale);
creatSaleBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Button clicked !", Toast.LENGTH_LONG).show();
}
});
creatSaleBtn.setClickable(true);
}
SwipeRefreshLayout's visibility should be GONE after recyclerview is empty.
of coarse recyclcerview is empty but it is still visible so your click events are caught by SwipeRefreshLayout witch is defined on top of LL1.
EDIT
instead of recyclerview, set swipe_refresh_db visibility to gone cos I doubt recyclerview is a child of swipe_refresh_dd so if you set recyclerview's visibility to gone, swipe_refresh_db is still visible and gets click events.
give it a try
How is that possible? Thanks! Should I put my View (RelativeLayout) on-top another View and make it invisible and when the user clicks the button it sets it to visible? Or is there another easier way that opens a Dialog(?) in the middle of the screen?
Thanks!
You need a layout to put the child view onto. Safest is Linear Layout since adding multiple child is easy
Fisrt create a xml file in layouts.
for eg in layout
add a file named say iv.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" >
<ImageView
android:id="#+id/iv_iv"
android:layout_width="200dp"
android:layout_height="120dp"
android:padding="2dp"
android:scaleType="fitCenter"
android:src="#drawable/person_default_page" />
In the layout where you want to add create a linear layout with some it say #+id/Row_id
Then in the code when you need to add the view
LinearLayout ll = = (LinearLayout) findViewById(R.id.Row_id);
ll.removeAllViews();
View element = LayoutInflater.from(this).inflate(R.layout.iv, ll, false);
ImageView image_iv = (ImageView) element.findViewById(R.id.ri_iv);
ll.addView(element);
Yes you can make it with an alert dialog. If you want to customize dialog use this
-First create an xml for your dialog
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:src="#drawable/header_logo"
android:layout_width="match_parent"
android:layout_height="64dp"
android:scaleType="center"
android:background="#FFFFBB33"
android:contentDescription="#string/app_name" />
<EditText
android:id="#+id/username"
android:inputType="textEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
android:hint="#string/username" />
<EditText
android:id="#+id/password"
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="16dp"
android:fontFamily="sans-serif"
android:hint="#string/password"/>
and override this method
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.dialog_signin, null))
// Add action buttons
.setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// sign in the user ...
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LoginDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
More info on Devlopper android
The app I am programming has a menu in which the user can pick a new building to build. The user will press "Buy" I would like this to create a new instance of the imagebutton that corresponds to that particular building. My current problem is that I only understand how to do this by setting up these in the xml file and setting them invisible until they buy it. I would like to dynamically create these buildings when they are bought. Is there a way to dynamically create an instance of an image button is this way? I don't really think including my source code is necessary here since I just need an example that works (most examples I have seen just don't work out). But if you would like to see some source code let me know.
Any help is appreciated. Thanks.
Code inside buy building button:
newColonyHut = new ImageButton(runGraphics.this);
newColonyHut.setImageResource(R.drawable.mainhut);
newColonyHut.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
layout.addView(newColonyHut);
Here is the xml:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<RelativeLayout
android:id="#+id/layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="0dp"
android:layout_marginRight="20dp" >
<Button
android:id="#+id/buyColonyHut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerHorizontal="true"
android:layout_marginBottom="5dp"
android:layout_below="#+id/colonyHutPrice" />
</LinearLayout>
You can create ImageView and dynamically add to layout you specified.
sample:
in oncreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button) findViewById(R.id.button1);
final LinearLayout test = (LinearLayout)findViewById(R.id.test);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageView image = new ImageView(MainActivity.this);
image.setImageResource(your_image_here);
image.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
test.addView(image);
}
});
the activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/home_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<LinearLayout
android:id="#+id/test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="horizontal">
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/layer"
android:text="Button" />
</LinearLayout>
As you can see ImageView is created when the button is clicked in the layout and then add it to the LinearLayout dynamically.
The LayoutParams is where you set the height and width of your ImageView respected the its parent which is the LinearLayout