I have a custom layout for my dialog box which shows the available product of a store in my app:
popstoreproduct.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="wrap_content"
android:orientation="vertical"
android:background="#color/backgroundgrey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginVertical="20dp">
<TextView
android:id="#+id/txtlist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="P R O D U C T"
android:textSize="16dp"
android:textStyle="bold"
android:layout_marginRight="15dp"
android:layout_marginLeft="20dp"
android:textColor="#color/text1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="L I S T"
android:textSize="16dp"
android:textColor="#color/text1"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/poprecycler"
android:layout_width="match_parent"
android:layout_height="500dp"
android:layout_gravity="center_horizontal"
android:overScrollMode="never"
android:layout_marginBottom="10dp"/>
</LinearLayout>
I have to use this layout as dialog in different activities so I have created a class that has a function which calls the dialog from MainActivity
Utility.java
public class Utility {
public Utility() {
}
public void popStoreProduct(Context context,ArrayList<Stock> mainlist,ArrayList<Stock> menuList){
final AlertDialog.Builder mBuild = new AlertDialog.Builder(context,R.style.DialogSlideAnim);
LayoutInflater inflater = LayoutInflater.from(context);
View layout = inflater.inflate(R.layout.popstoreproduct,null);
final RecyclerView precycler =(RecyclerView)layout.findViewById(R.id.poprecycler);
LinearLayoutManager playoutManager = new LinearLayoutManager(context);
precycler.setLayoutManager(playoutManager);
precycler.setHasFixedSize(true);
AdapterPopStoreProduct pAdapter = new AdapterPopStoreProduct(context,mainlist,menuList);
precycler.setAdapter(pAdapter);
mBuild.setView(layout);
final AlertDialog dialog = mBuild.create();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().getAttributes().gravity = Gravity.BOTTOM |Gravity.CLIP_HORIZONTAL;
dialog.show();
}
}
When I run the app and call for the function in my main activity, it crashes and gives the following error that points to the dialog.show() line:
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
at com.example.myapp.Classes.Utility.popStoreProduct(Utility.java:288)
I don't understand what is wrong with the code. Please Help
PS: I have use slide animation in my dialog that slides from the bottom.
show your styles file and Activitys manifest declaration. as the error say your style for Activity must be/extends Theme.AppCompat. for example:
android:theme="#style/Theme.AppCompat.Light"
you can also set this theme for all Activities adding above line to <application tag instead of each Activity declaration
Related
I know that this question have been asked a few times, but none of the solutions I came across worked for me, hence this topic. As the title states - I want to set dialog's outer margin:
PurchaseDetailsDialogFragment
public class PurchaseDetailsDialogFragment extends DialogFragment {
private static final String MAX_AMOUNT = "maxAmount";
private static final String UNIT_PRICE = "unitPrice";
private static final String PICKUP_TIME_FROM = "pickupTimeFrom";
private static final String PICKUP_TIME_TO = "pickupTimeTo";
public PurchaseDetailsDialogFragment() { }
public static PurchaseDetailsDialogFragment newInstance(int maxAmount, float unitPrice, String pickupTimeFrom, String pickupTimeTo) {
PurchaseDetailsDialogFragment fragment = new PurchaseDetailsDialogFragment();
Bundle args = new Bundle();
args.putInt(MAX_AMOUNT, maxAmount);
args.putFloat(UNIT_PRICE, unitPrice);
args.putString(PICKUP_TIME_FROM, pickupTimeFrom);
args.putString(PICKUP_TIME_TO, pickupTimeTo);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
int maxAmount = getArguments().getInt(MAX_AMOUNT);
float unitPrice = getArguments().getFloat(UNIT_PRICE);
String pickupFrom = getArguments().getString(PICKUP_TIME_FROM);
String pickupTo = getArguments().getString(PICKUP_TIME_TO);
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getContext();
FragmentPurchaseDetailsDialogBinding binding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.fragment_purchase_details_dialog,
null,
false);
binding.setDataContext(new PurchaseDetailsViewModel(context));
AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.DialogTheme)
.setView(binding.getRoot())
.create();
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
return dialog;
}
}
fragment_purchase_details_dialog
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/dialog">
<data>
<variable
name="dataContext"
type="com.myapp.viewModels.PurchaseDetailsViewModel" />
</data>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="80dp"
android:paddingTop="20dp"
android:layout_centerHorizontal="true"
android:background="#color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/choose_amount"
style="#style/Widget.App.PurchaseTextViewTitle" />
</FrameLayout>
<LinearLayout
android:id="#+id/dialogCentralContent"
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:layout_marginTop="80dp"
android:background="#color/dirtyWhite">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="74" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="46dp"
android:layout_centerHorizontal="true">
<Button
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginTop="6dp"
android:background="#drawable/button_filled"
android:text="-"
style="#style/Widget.App.PurchaseIncDecButton" />
<FrameLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#drawable/edittext_white_rounded">
<EditText
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="center_horizontal"
android:maxLines="1"
style="#style/Widget.App.PurchaseAmountEditText" />
</FrameLayout>
<Button
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginTop="6dp"
android:background="#drawable/button_filled"
android:text="+"
style="#style/Widget.App.PurchaseIncDecButton" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_below="#+id/dialogCentralContent"
android:text="#string/buttonBuyText"
android:background="#drawable/button_submit"
style="#style/Widget.App.SubmitButton" />
</RelativeLayout>
</layout>
Now with the above code only, my dialog takes up whole width of the screen. If I however do this, in the fragment java code:
AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.DialogTheme) /// the rest of the code
And add a theme:
<resources>
<style name="DialogTheme" parent="#android:style/Theme.Material.Dialog.Alert">
<item name="android:windowMinWidthMajor">380dp</item>
<item name="android:windowMinWidthMinor">380dp</item>
</style>
</resources>
Then some funky stuff happens. On API23 all looks fine, while on API19 and below (didn't check apis between 19 and 23) the dialog is 100% wide and aligned to top of the screen. How to make it work the way I'd like it to?
There's one really simple solution to this. Just put your layout inside, for example a FrameLayout and set appropriate paddings on the outer layout element. Then everything is gonna look the same across all apis:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/defaultMargin"
android:paddingRight="#dimen/defaultMargin">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RelativeLayout>
</FrameLayout>
Have you tried this ?
How to Build AppCompatDialog From AlertDialog.Builder or Equivalent?
It suggests you to use android.support.v7.app.AlertDialog rather than android.app.AlertDialog
So for dialogs with multiple choices try AppCompactDialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.DialogTheme)
.setView(binding.getRoot())
.create();
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
AppCompatDialog alert = builder.create();
alert.show();
I have not tried this. Let me know if this works.
<item name="android:windowMinWidthMinor">380dp</item>
this will keep the dialog width to be a mininum of 380dp, but if device width < 380dp, then the dialog will take up the whole available space
If you tested with a device with a smaller width(very likely if the device has a lower api, for example Galaxy Nexus's width is 360dp), of course it will take up the whole width.
It's better to specify the minWidth as a percentage
for your particular case, to achieve a predefined margin(without modifying the Window's layout attributes programmatically), we can set the min width to be 100%
<item name="android:windowMinWidthMinor">100%</item>
and use an inset drawble as the windowBackground, which is already the case if you are using AppCompat
<item name="android:windowBackground">#drawable/abc_dialog_material_background</item>
abc_dialog_material_background:
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="16dp"
android:insetTop="16dp"
android:insetRight="16dp"
android:insetBottom="16dp">
<shape android:shape="rectangle">
<corners android:radius="#dimen/abc_dialog_corner_radius_material" />
<solid android:color="#android:color/white" />
</shape>
</inset>
I wanted to customise android Dialog to make it look like a floating dialog as below which is suggested in https://material.google.com/components/dialogs.html#dialogs-simple-dialogs
I tried creating a DialogFragment in which onCreateDialog returns a Dialog with a view whose root is a CardView.But couldn't get the expected result.Can I have some suggestions on how to achieve this?
My layout looks like this,
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center|top"
card_view:cardElevation="5dp"
card_view:cardPreventCornerOverlap="false">
//Contents come here
</android.support.v7.widget.CardView>
and in code,
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new Dialog(getActivity());
View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_font_selection,null,false);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
float width = (I am getting screen width here) * .80f;
dialog.getWindow().setLayout((int) width, ViewGroup.LayoutParams.WRAP_CONTENT);
return dialog;
}`
but the result looks like this,
Instead of getting elevation I was getting a black shade
AlertDialog.Builder mydialog = new AlertDialog.Builder( context);
mydialog.setTitle("Set backup accounts");
mydialog.setItems(CharSequence[] items, OnClickListener);
mydialog.show();
mydialog.setContentView(R.layout.mydialogLayout);
This in your activity/fragment. And so declare your layout as follow:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<TextView
android:id="#+id/myID1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
After that, if you want to handle the clicks just do that:
TextView myView1 = (TextView) mydialog.findViewById(myID1);
myView1.setOnClickListener(...);
MaterialAlertDialogBuilder is now available for Android:
material.io/develop/android/components/dialog
I wrote an application which have to call dialog to get name. I need the custom view in dialog so I used .setContentView(). But in android with api less 20 I have problems with displaying it.
This is calling dialog:
public void setName(View v) {
nameDialog = new Dialog(this);
//using our dialog
nameDialog.setContentView(R.layout.new_name);
EditText text = (EditText) nameDialog.findViewById(R.id.form2_dialog_name);
//if we have previous name we show it
if (haveName) {
text.setText(((Button) findViewById(R.id.form2_name_button)).getText());
}
//request focus and call keyboard for input name
text.requestFocus();
text.selectAll();
nameDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
nameDialog.show();
}
the xml file:
<?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:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_dark"
tools:context=".CreateNoteActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/form2_dialog_name_of_event"
android:id="#+id/textView11" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text=""
android:ems="10"
android:id="#+id/form2_dialog_name"
android:maxLines="1" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end">
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/close_button"
android:id="#+id/button8"
android:onClick="onCancelDialog"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/okay_button"
android:id="#+id/okay_form2_dialog_button"
android:onClick="onFinishDialog" />
</LinearLayout>
</LinearLayout>
How it looks when api upper then 20:
http://i.imgur.com/pJ1oZky.png
Less then 20:
http://i.imgur.com/TJGEwXh.png
OK the answer is quite simple: Use the android.support.v7.app.AlertDialog
Your setName will have to look like this then:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.new_name, null);
builder.setView(dialogView);
EditText text = (EditText) dialogView.findViewById(R.id.form2_dialog_name);
//if we have previous name we show it
if (haveName) {
text.setText(((Button) findViewById(R.id.form2_name_button)).getText());
}
//request focus and call keyboard for input name
text.requestFocus();
text.selectAll();
AlertDialog dialog = builder.create();
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dialog.show();
I guess you will have to play a little with your layout file because the buttons are quite a bit too far away but I think this will be just a little problem ;)
Is there any similar theme generator as HoloColors or Action Bar Style Generator which would help us change theme of Dialogs and AlertDialogs in our apps?
My app uses Holo theme and I managed to change style of views such as EditTexts and Buttons but they remain unchanged when they appear in a Dialog. I would also like to change color of the blue line under a title.
I've found a few question and answers related to this topic but they practically say it's not even possible. I cannot believe it isn't.
At least for the AlertDialog it is possible. here i posted my solution of a function which is called at some point (for example button click) in your code and creates an alert dialog own layout over your screen.. the layout is a normal layout.xml which you can define the way you want. works perfect for me!
private void showAddUserGeneratedStationDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
AmplifyActivity.this);
LayoutInflater inflater = getLayoutInflater();
//inflate your layout.xml
alertDialog
.setView(inflater.inflate(R.layout.dialog_add_station, null));
//show dialog over activity screen
final AlertDialog ad = alertDialog.show();
//put actions to your ui-elements
Button cancelBtn = (Button) ad
.findViewById(R.id.list_user_generated_cancelBU);
cancelBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ad.cancel();
}
});
Button doneBtn = (Button) ad
.findViewById(R.id.list_user_generated_doneBU);
doneBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//get sth from your layout f.e. some textInput
String stationUrl = ((TextView) ad
.findViewById(R.id.list_user_generated_stationURLInput))
.getText().toString();
// did some other things
ad.dismiss();
}
});
}
and my layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_user_generated_addStationDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#99000000"
android:clickable="true"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:layout_width="300dp"
android:layout_height="200dp"
android:padding="10dp"
android:background="#000"
android:orientation="vertical" >
<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="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/list_user_generated_cancelBU"
style="#style/ButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|right"
android:text="#string/cancel" />
<TextView
style="#style/AmplifyHeadlineElement"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="#string/list_userGenerated_addStation" />
<Button
android:id="#+id/list_user_generated_doneBU"
style="#style/ButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|right"
android:text="#string/done" />
</LinearLayout>
<EditText
android:id="#+id/list_user_generated_stationURLInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginTop="10dp"
android:background="#FFF"
android:ems="10"
android:hint="#string/list_userGenerated_addUrlExample"
android:inputType="textNoSuggestions" >
</EditText>
<!-- MORE BUT I DELETED IT FOR BETTER OVERVIEW -->
</LinearLayout>
</LinearLayout>
i custom a dialog :
public class CustomizeDialog extends Dialog implements OnClickListener {
Button close;
TextView tv;
public CustomizeDialog(Context context,String Stringcontent) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.custom_diolog_main);
tv=(TextView) findViewById(R.id.content);
tv.setText(Stringcontent);
close = (Button) findViewById(R.id.close);
close.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == close)
dismiss();
}
}
the xml is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="100dip"
android:orientation="vertical"
android:background="#drawable/custom_diolog_bg"
android:layout_width="250dip">
<TextView android:layout_height="wrap_content"
android:textColor="#000"
android:textStyle="bold"
android:textSize="18sp"
android:id="#+id/content"
android:layout_marginLeft="15dip"
android:layout_marginTop="5dip"
android:layout_alignParentTop="true"
android:layout_width="250dip"
android:text=" Custom Dialog "/>
<Button android:layout_width="70dip"
android:layout_marginLeft="80dip"
android:background="#drawable/custom_dialog_button_bg"
android:layout_alignParentBottom="true"
android:layout_height="40dip" android:text="关闭"
android:id="#+id/close"></Button>
</RelativeLayout>
my dialog is vrry well,but custom_diolog_bg is a rounded rectangle image,and when i show my dialog ,it show a system Frame behide my custom,so i used this.getwindow.setBackgroundDrawable(null),then the system Frame seems have remove but only the Four Corners not remove,we also see dark Four Corners,because i used the rounded rectangle image.so my question how to remove all the Frame so that my dialog seem Very well
the pic is http://i.stack.imgur.com/EG7oz.jpg ,so you can see there is dark frame in the last,how to remove it? thank you
Solution that worked for me
<style name="DialogTheme" parent="#android:style/Theme.Dialog">
<item name="android:windowBackground">#android:color/transparent</item>
</style>
Dialog dialog = new Dialog(this, R.style.DialogTheme);
Use following lines before calling setContentView() :-
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
will work perfectly.
Dialog mydialog = new dialog (this,android.R.style.Theme_Translucent_NoTitleBar);
instead of calling
super(context);
call
super(context, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
Update : Use this xml layout instead
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="100dip"
android:orientation="vertical"
android:background="#drawable/custom_diolog_bg"
android:layout_width="250dip">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true">
<TextView
android:layout_height="wrap_content"
android:textColor="#000"
android:textStyle="bold"
android:textSize="18sp"
android:id="#+id/content"
android:layout_marginLeft="15dip"
android:layout_marginTop="5dip"
android:layout_alignParentTop="true"
android:layout_width="250dip"
android:text=" Custom Dialog " />
<Button
android:layout_width="70dip"
android:layout_marginLeft="80dip"
android:background="#drawable/custom_dialog_button_bg"
android:layout_alignParentBottom="true"
android:layout_height="40dip"
android:text="关闭"
android:id="#+id/close"></Button>
</LinearLayout>
</RelativeLayout>
Try this it worked for me like a charm.
ContextThemeWrapper wrapper = new ContextThemeWrapper(this, android.R.style.Theme_Holo);
final LayoutInflater inflater = (LayoutInflater) wrapper.getSystemService(LAYOUT_INFLATER_SERVICE);
AlertDialog.Builder builder = new AlertDialog.Builder(wrapper);