Show entire bottom sheet with EditText above Keyboard - android

I'm implementing a UI where a bottom sheet will appear above the keyboard with an EditText for the user to enter a value. The problem is the View is being partially overlapped by the keyboard, covering up the bottom of the bottom sheet.
Here is the Bottom Sheet and no keyboard.
Here is the Bottom Sheet with the keyboard showing.
What's the best method to ensure the entire Bottom Sheet is shown?
Thanks.

Just reposting #jblejder from this question Keyboard hides BottomSheetDialogFragment since it worked for me, to make it easier for others to find:
The most convenient way that I found to change this is by creating style:
<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
And set this in onCreate method of your BottomSheetDialogFragment:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogStyle)
}
This is how it looks on my device:
==== UPDATE ====
As already mentioned in the Comments a few times, you might also need to set the state of the BottomSheetDialog to STATE_EXPANDED like in Nordknight's answer below
dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
},0);
}
});

This might be a redundant answer. Although just pointing out the issue.
If you're using BottomSheetDialogFragment, the only way is to enable the attribute android:windowIsFloating to true. This will enable the whole window to be on top of whatever is trying to take the space behind it.
<style name="BottomSheetDialogThemeNoFloating" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
</style>
Then in your onCreate() of your dialog, set this style.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// set the window no floating style
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppRoundedBottomSheetDialogThemeNoFloating)
}
This is handy for those who frequently use bottom sheets and may want to deal with EditText and soft keyboard overlapping each other.
Note: The class KeyboardUtil by mikepenz has an issue in which on certain phones, the content view with input field is automatically pushed above keyboard despite giving bottom padding to the whole content view supplied.

dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
},0);
}
});
This code works fine at Fragment's onCreateView method (thanks for ADM)

Some answers seem to do the trick better than others but will need modification when using the new material design components instead of the older support libraries while also using kotlin
Hope this will help someone.
BottomSheetDialog(this, R.style.DialogStyle).apply {
setContentView(layoutInflater.inflate(R.layout.bottom_sheet, null))
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
findViewById<EditText>(R.id.time_et)?.requestFocus()
show()
}
layout/bottom_sheet.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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="wrap_content"
android:background="#ffffff"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Time"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<EditText
android:id="#+id/time_et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="numberSigned"
android:minWidth="50dp"
android:text="15" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:text="min" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#000"
android:text="Save"
android:textColor="#fff" />
</LinearLayout>
</ScrollView>
styes.xml (Split for v-21 for using statusBarColor)
<style name="DialogStyle" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>

A BottomSheetDialog can be helpful for this. it will open with Softkeyboard open with focus on edit text.But user can still close the Softkeyboard and Dialog will be reset to Bottom. Again focusing will make dialog appear at top of Softkeyboard.
public void showDialog() {
final BottomSheetDialog dialog=new BottomSheetDialog(this);
dialog.setContentView(R.layout.item_dialog);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dialog.show();
}
You can make the BottomSheetDialog expanded over keyboard . But for this you need to call it after SoftKeyboard Open. the Expand code is .
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
I have tested it on DialogInterface.OnShowListener() but its not working . Tested with it 1 second delay its working . But Delay is not the solution . You need to figure out the on which action you should expand the dialog.
final BottomSheetDialog dialog=new BottomSheetDialog(this);
dialog.setContentView(R.layout.item_dialog);
dialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
FrameLayout bottomSheet = (FrameLayout) dialog.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
},2000);
dialog.show();

An updated answer for those using Material Components theme, and also an improved answer to remove the need to add anything into each dialog's onCreate().
In your main AppTheme style, you can add the attribute bottomSheetDialogTheme to apply the style to all of your BottomSheetDialogFragments:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<item name="colorAccent">#color/accent</item>
<item name="bottomSheetDialogTheme">#style/BottomSheetDialogStyle</item>
</style>
So with the above, no need to add anything to your BottomSheetDialogFragment code.
And then, as previous answers, your Dialog style, noting to also match the style to the same Material Components library (or you'll get some weird looking buttons, edittexts etc):
<style name="BottomSheetDialogStyle" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<item name="colorAccent">#color/accent</item>
</style>
Note that I am adding my app theme colors back in here; as you can't have multiple inheritance in Android styles, you may want these colors defining here so any buttons and accents align with the rest of your app.

private fun enterMobileNumberPopUp() {
val dialog = BottomSheetDialog(this,R.style.DialogStyle)
val view = layoutInflater.inflate(R.layout.layout_otp, null)
dialog.setContentView(view)
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
dialog.show()}
THIS IS THE MOST EASY WAY AND BEST WAY TO HANDLE BOTTOM SHEET DIALOG
YOU CAN CALL THIS IN METHOD
<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
Style reference

This one working
BottomSheetDialog dialog = new BottomSheetDialog(this, R.style.DialogStyle);
View sheetView = getLayoutInflater().inflate(R.layout.dialog_remark, null);
Objects.requireNonNull(dialog.getWindow())
.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE);
dialog.setContentView(sheetView);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
View bottomSheetInternal = d.findViewById(com.google.android.material.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
dialog.show();
add this style to your styles.xml
<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustPan</item>
</style>
add your layout like this
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/scrollview"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="8dp"
android:fontFamily="#font/montserratmedium"
android:text="Add Remarks"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:fontFamily="#font/montserratmedium"
android:text="Branch"
android:textColor="#8B8B8B"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:fontFamily="#font/montserratmedium"
android:text="BLR-CO-SINDHUBHAVAN-384"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:fontFamily="#font/montserratmedium"
android:text="Enter Remarks"
android:textColor="#8B8B8B"
android:textSize="18sp" />
<EditText
android:id="#+id/input_remark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="8dp"
android:background="#drawable/remark_inputbg"
android:gravity="start"
android:inputType="textMultiLine"
android:lines="5" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="1"
android:background="#drawable/reset_bg"
android:padding="8dp"
android:text="CANCEL" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="1"
android:background="#4F4DBB"
android:padding="8dp"
android:text="CANCEL"
android:textColor="#android:color/white" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</ScrollView>

bottomSheetDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
It will work for sure.

Just write the following programmatically
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
dialog.window?.setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE or
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
);
}

Kotlin, +viewBinding, +by using the accepted answer's dialog style
val bottomSheet = BottomSheetDialog(this, R.style.BottomSheetDialogStyle)
val binding = [YourSheetBinding].inflate(LayoutInflater.from(YourActivity.this))
bottomSheet.setContentView(binding.root)
bottomSheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED
bottomSheet.show()

override fun onStart() {
super.onStart()
bottomSheetBehavior?.skipCollapsed = true
bottomSheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
Putting this in BottomSheet helped without setting styles and without ScrollView
(correct me if I'm wrong or if I'm missing something)

This trick solved me
in manifest put
android:windowSoftInputMode="adjustPan"
in your activity
and
bottomSheetDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
bottomSheetDialog.getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);

For this, I found an AlertDialog worked best. While it doesn't sit flush against the bottom or side of the screen, it still looks good enough.
First, create the AlertDialog with your view.
val view = LayoutInflater.from(context).inflate(R.layout.alert, null)
dialog = AlertDialog.Builder(context)
.setView(view)
.create()
Next, set the gravity.
dialog.window.attributes.gravity = Gravity.BOTTOM
And finally, show it.
dialog.show()
You can also bind the keyboard to stay with the dialog, by using an onDismissListener.
After showing the AlertDialog, I force up the keyboard.
Call this method, passing in your EditText.
fun showKeyboard(view: View?) {
if (view == null) return;
val imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
And for dismissing within the onDismissListener.
private fun hideKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
}

My answer might be useful for someone who is still looking for solution. If keyboard is covering edittext in BottomSheetDialogFragment then in setupDialog() method create instance of a class KeyboardUtil and pass your rootview.
#Override
public void setupDialog(final Dialog dialog, int style) {
super.setupDialog(dialog, style);
View view = View.inflate(getActivity(), R.layout.reopen_dialog_layout, null);
new KeyboardUtil(getActivity(), view);
}
Create a new class
public class KeyboardUtil {
private View decorView;
private View contentView;
//a small helper to allow showing the editText focus
ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
decorView.getWindowVisibleDisplayFrame(r);
//get screen height and calculate the difference with the useable area from the r
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int diff = height - r.bottom;
//if it could be a keyboard add the padding to the view
if (diff != 0) {
// if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
//check if the padding is 0 (if yes set the padding for the keyboard)
if (contentView.getPaddingBottom() != diff) {
//set the padding of the contentView for the keyboard
contentView.setPadding(0, 0, 0, diff);
}
} else {
//check if the padding is != 0 (if yes reset the padding)
if (contentView.getPaddingBottom() != 0) {
//reset the padding of the contentView
contentView.setPadding(0, 0, 0, 0);
}
}
}
};
public KeyboardUtil(Activity act, View contentView) {
this.decorView = act.getWindow().getDecorView();
this.contentView = contentView;
//only required on newer android versions. it was working on API level 19
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
/**
* Helper to hide the keyboard
*
* #param act
*/
public static void hideKeyboard(Activity act) {
if (act != null && act.getCurrentFocus() != null) {
InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
}
}
public void enable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
public void disable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
}

See https://stackoverflow.com/a/61813321/2914140:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
return dialog
}
But if a layout is not tall enough, you can use https://stackoverflow.com/a/66287187/2914140 instead. It will open BottomSheetDialog almost fullscreen:
<style name="BottomSheetDialogTheme" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
</style>

Fiddling with BottomSheetDialogFragmentwasn't really worth it. So I just changed it to a simple DialogFragment and just set its gravity to bottom:
window.setGravity(Gravity.BOTTOM);
Worked like a charm.

Related

Android Custom Snackbar: can't remove margins

Regardless of whether or not it is a good idea to create a custom Snackbar, I have a custom Snackbar and I can't seem to get rid of the margins. I've tried several things such as adjusting in code and in layout as shown below. Nothing seems to work.
I am using the approach laid out by Yakiv here:
final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) snackBarView.getLayoutParams();
params.setMargins(0,0,0,0);
and other approaches such as
android:layout_marginLeft="0dp"
android:layout_marginStart="0dp"
android:paddingLeft="0dp"
android:paddingStart="0dp" ...
The Snackbar:
My layout file:
<view
xmlns:android="http://schemas.android.com/apk/res/android"
class="android.support.design.internal.SnackbarContentLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/realBlack"
android:layout_marginLeft="0dp"
android:layout_marginStart="0dp"
android:paddingLeft="0dp"
android:paddingStart="0dp">
<TextView
android:id="#+id/snackbar_text"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_weight="1"
android:paddingTop="#dimen/design_snackbar_padding_vertical"
android:paddingBottom="#dimen/design_snackbar_padding_vertical"
android:paddingLeft="#dimen/design_snackbar_padding_horizontal"
android:paddingRight="#dimen/design_snackbar_padding_horizontal"
android:textAppearance="#style/TextAppearance.Design.Snackbar.Message"
android:maxLines="#integer/design_snackbar_text_max_lines"
android:layout_gravity="center_vertical|left|start"
android:ellipsize="end"
android:textAlignment="viewStart"
android:text="get some"/>
<Button
android:id="#+id/snackbar_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/design_snackbar_extra_spacing_horizontal"
android:layout_marginStart="#dimen/design_snackbar_extra_spacing_horizontal"
android:layout_gravity="center_vertical|right|end"
android:minWidth="48dp"
android:visibility="gone"
android:textColor="?attr/colorAccent"
style="?attr/borderlessButtonStyle"/>
</view>
The calling code:
_firmwareSnackbar = CustomSnackbar.make((ViewGroup) _rootView, Snackbar.LENGTH_INDEFINITE);
_firmwareSnackbar.setText(_flipper.getContext().getString(R.string.settings_firmware_available));
_firmwareSnackbar.setAction(_flipper.getContext().getString(R.string.settings_firmware_start), new View.OnClickListener() {
#Override
public void onClick(View view) {
_firmwareSnackbar.dismiss();
_firmwareSnackbar = null;
}
});
_firmwareSnackbar.show();
If you are using material components, then add this code to your style.xml file under values
<style name="Widget.SnackBar" parent="Widget.MaterialComponents.Snackbar">
<item name="android:layout_margin">0dp</item>
</style>
then
<style name="AppTheme" parent="Theme.MaterialComponents.NoActionBar">
<!-- Customize your theme here. -->
<item name="snackbarStyle">#style/Widget.SnackBar</item>
</style>
This will change margin for all existing snackBar in the app. So if you want to show a gap around SnackBar you can use padding.
val snackBar = Snackbar.make(homeLayout, "", Snackbar.LENGTH_INDEFINITE)
val snackBarLayout = snackBar.view as Snackbar.SnackbarLayout
snackBarLayout.setPadding(8, 0, 8, 0)
In dimens.xml.
Use this:
<dimen name="design_snackbar_padding_horizontal">0dp</dimen>
But remember that this will get applied to all the snackbars in your application.
Before showing the Snackbar you can remove the parent layout padding in the following way:
//...
_firmwareSnackbar.getView().setPadding(0,0,0,0);
_firmwareSnackbar.show();
Add to theme of App or Activity <item name="snackbarStyle">#style/Widget.Design.Snackbar</item>
You shoud remove paddings from a parent view:
View snackBarLayout = findViewById(R.id.mainLayout);
Snackbar globalSnackbar = Snackbar.make(snackBarLayout, "", Snackbar.LENGTH_INDEFINITE);
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) globalSnackbar.getView();
layout.setPadding(0,0,0,0);

Custom Dialog filling the screen height

I am trying to create a custom Dialog, and is working just fine, but the Dialog is filling the whole screen height. I've done some unsuccessful research on the internet but I don't have a lot of time for this task, if anyone knows why is this happening I appreciate it hard.
here is the onCreateDialog():
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder= new AlertDialog.Builder(getContext());
LayoutInflater inflater= (LayoutInflater) builder.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.dialog__warning, mContainer, false);
txtWarning = (TextView)view.findViewById(R.id.txtWarning);
if(messageWarning.length()>0)
{
txtWarning.setText(messageWarning);
}
btnOkDialog = (Button) view.findViewById(R.id.btnOkDialog);
btnOkDialog.setOnClickListener(MyListener);
btnCancelDialog = (Button) view.findViewById(R.id.btnCancelDialog);
btnCancelDialog.setOnClickListener(MyListener);
builder.setView(view);
return builder.create();
}
and the xml of dialog_warning:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#b1b0b0"
tools:context="ipat.johanbayona.gca.ipat.NewEvidence.Dialog_Warning">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="25sp"
android:id="#+id/txtWarning"
android:text="Mensaje error" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK"
android:id="#+id/btnOkDialog"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="10dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:id="#+id/btnCancelDialog"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="10dp"
/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#b1b0b0"
tools:context="ipat.johanbayona.gca.ipat.NewEvidence.Dialog_Warning">
Change "layout_height" to wrap_content. You fixed height and width, that may be the problem depending on your screen size.
try creating your own theme for the dialog, something like this
<style name="AppDialog">
<item name="android:windowFrame">#null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">#null</item>
</style>
and set this theme passing to the dialog's super constructor with R.style.AppDialog
upd.
it's not the builder's constructor. you should create your own class that extends the AlertDialog, override it's onCreate and the super constructor and your class should be something like this
public class YourDialog extends Dialog {
public YourDialog(#NonNull Context context) {
super(context, R.style.AppDialog);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog__warning);
txtWarning = (TextView) findViewById(R.id.txtWarning);
if(messageWarning.length()>0)
{
txtWarning.setText(messageWarning);
}
btnOkDialog = (Button) findViewById(R.id.btnOkDialog);
btnOkDialog.setOnClickListener(MyListener);
btnCancelDialog = (Button) findViewById(R.id.btnCancelDialog);
btnCancelDialog.setOnClickListener(MyListener);
}
}
overriding the main constructor, and passing the R.style.AppDialog should do the trick. all you need is to call where you want to show the dialog new YourDialog(context).show();
note that you don't need to call manually the layout inflater to pass your own contentview, just calling the setContentView with resId will automatically inflate the view beneath.

How to set dialog window background to transparent, without affecting its margin

Currently, I have the following dialog, which I will perform expand/ collapse animation on its items.
This dialog is created via the following code
import android.support.v7.app.AlertDialog;
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
final AlertDialog dialog = builder.setView(view).create();
final ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
ViewTreeObserver obs = view.getViewTreeObserver();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
// http://stackoverflow.com/questions/19326142/why-listview-expand-collapse-animation-appears-much-slower-in-dialogfragment-tha
int width = dialog.getWindow().getDecorView().getWidth();
int height = dialog.getWindow().getDecorView().getHeight();
dialog.getWindow().setLayout(width, height);
}
});
However, when animation being performed, here's the side effect.
Note, the unwanted extra white region at the dialog after animation, is not caused by our custom view. It is the system window white background of the dialog itself.
I tend to make the system window background of the dialog, to become transparent.
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
final AlertDialog dialog = builder.setView(view).create();
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Although the unwanted white background is no longer seen, the original margin of the dialog is gone too. (The dialog width is now full screen width)
How can I make it transparent, without affecting its margin?
There's a pretty easy way to do that:
You need to "modify" the Drawable that is being used as a background of the Dialog. Those sort of Dialogs use an InsetDrawable as a background.
API >= 23
Only SDK API 23+ allows you to get the source Drawable wrapped by the InsetDrawable (getDrawable() method). With this, you can do whatever you want - e.g. change color to something completely different (like RED or something). If you use this approach remember that the wrapped Drawable is a GradientDrawable and not a ColorDrawable!
API < 23
For lower APIs your ("elegant") options are very limited.
Fortunately you don't need to change the color to some crazy value, you just need to change it to TRANSPARENT. For this you can use setAlpha(...) method on InsetDrawable.
InsetDrawable background =
(InsetDrawable) dialog.getWindow().getDecorView().getBackground();
background.setAlpha(0);
EDIT (as a result of Cheok Yan Cheng's comments):
or you can actually skip casting to InsetDrawable and get the same result. Just remember that doing so will cause the alpha to be changed on the InsetDrawable itself and not on the Drawable that is wrapped by the InsetDrawable.
Try to below Theme:
<style name="TransaparantDialog">
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowFrame">#null</item>
<item name="android:windowTitleStyle">#null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:background">#android:color/transparent</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
</style>
Try below code to apply Theme to AlertDialog.Builder:
final AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.TransaparantDialog));
...
dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
I hope help you !
The background image abc_popup_background_mtrl_mult which is part of the compat library contains already a margin in the picture information.
This is why the margin goes away when you remove the background image. I strongly recommend not to use the ViewTreeObserver, it will been called multiple times and can cause performance issues. Better work with the screen size:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Your problem is properly in the layout try to check the views with the Hierarchy viewer.
just add this line after show dialog. I would prefer using Dialog instedof using AlertDialog
dialog.getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
Let's start with Google recommendation which says to use DialogFragment instead of a simple Dialog.
#rekire is right that margins set by drawable, going forward it is set by either 9 patch or programmatically depending on theme.
So you either can set your padding to your content view or create dialog using DialogFragment here is an example which changes height of dialog based on it's content, and note you don't need to use tree observer which is as mentioned before may cause performance issue.
So the example
dialog_confirm.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">
<LinearLayout android:id="#+id/container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:orientation="vertical"
android:animateLayoutChanges="true"
android:padding="15dp">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="A label text"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque mauris mi, dictum a lectus ut, facilisis"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove Me"/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove Me"/>
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove Me"/>
<!-- as much content as you need -->
</LinearLayout>
</ScrollView>
Note: I wrapped everything into scroll view and set padding you can skip it if you want.
ConfirmDialog.java
//here goes package name and imports
/**
* Created by Vilen - virtoos.com;
* fragment dialog example
*/
public class ConfirmDialog extends DialogFragment implements View.OnClickListener {
private Button button1;
private Button button2;
private Button button3;
private LinearLayout containerLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dialog_confirm, container, false);
containerLayout = (LinearLayout)v.findViewById(R.id.container);
button1 = (Button)v.findViewById(R.id.button1);
button2 = (Button)v.findViewById(R.id.button2);
button3 = (Button)v.findViewById(R.id.button3);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// make background transparent if you want
//getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button1:
containerLayout.removeView(button1);
break;
case R.id.button2:
containerLayout.removeView(button2);
break;
case R.id.button3:
containerLayout.removeView(button3);
break;
}
}
}
and finally you can show your dialog with this piece of code
ConfirmDialog confirmDialog = new ConfirmDialog();
confirmDialog.show(getSupportFragmentManager(), "dialog");
I will not go into details why Fragment dialog is better but one thing is clear that you can encapsulate logic for it and have separate class.
Hope this solves your issue.
What should be there is what you didn't show, I'm not sure it is something you didn't know or it is already there so you don't think it is necessary to show.
Set theme to Dialog, that puts entire activity as one Dialog. I don't think you did it, otherwise AlertDialog would not be there.
I'm a bit lost your description, but there is that little <shape/> XML that is much more powerful then a 9-patch, and use RelativeLayout will help.

AlertDialog setCustomTitle styling to match standard AlertDialog title

I'm working on an Android app and I have an AlertDialog subclass. I would like to put 2 ImageButtons on the right side of the title area of the dialog (similar to an the ActionBar in an Activity). I'm using setCustomTitle() to do this, which replaces the title area with a custom view of my own creation. This works fine, but the styling of my custom title area is not the same as the standard title styling (height, color, separator, etc).
My question is: with the understanding that styling varies by OS version and manufacturer, how can I style my custom title in the dialog so that it will match the standard title styling for other AlertDialogs?
Here is an image of anAlertDialog with standard styling (this is from ICS, but I want to be able to match any variant -- not this particular style)
And here is an image of an AlertDialog with custom title and buttons (note how the title height and color don't match the standard dialog)
EDIT: I can't just add the ImageButtons to the standard title view, because I don't have access to it. If you know of a (reliable, non-hack) method for me to add buttons to the standard title area, I would accept that as well.
Given that there is new interest in this question, let me elaborate about how I "solved" this.
First, I use ActionBarSherlock in my app. This is not necessary, I suppose, though it helps a lot because the styles and themes defined in the ABS project allow me to mimic the Holo theme on pre-ICS devices, which provides a consistent experience in the app.
Second, my "dialog" is no longer a dialog -- it's an activity themed as a dialog. This makes manipulation of the view hierarchy simpler, because I have complete control. So adding buttons to the title area is now trivial.
Here are the screenshots (2.2 device and 4.1 emulator). Note that the only significant styling difference is the EditText, which I have chosen not to address.
Here is my onCreate in my dialog activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_tag);
setTitle(R.string.tag_dialog_title);
View sherlockTitle = findViewById(android.R.id.title);
if (sherlockTitle != null) {
sherlockTitle.setVisibility(View.GONE);
}
View sherlockDivider = findViewById(R.id.abs__titleDivider);
if (sherlockDivider != null) {
sherlockDivider.setVisibility(View.GONE);
}
// setup custom title area
final View titleArea = findViewById(R.id.dialog_custom_title_area);
if (titleArea != null) {
titleArea.setVisibility(View.VISIBLE);
TextView titleView = (TextView) titleArea.findViewById(R.id.custom_title);
if (titleView != null) {
titleView.setText(R.string.tag_dialog_title);
}
ImageButton cancelBtn = (ImageButton) titleArea.findViewById(R.id.cancel_btn);
cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
cancelBtn.setVisibility(View.VISIBLE);
ImageButton okBtn = (ImageButton) titleArea.findViewById(R.id.ok_btn);
okBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// do stuff here
finish();
}
});
okBtn.setVisibility(View.VISIBLE);
}
}
And here is the relevant layout for the activity:
<LinearLayout
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<LinearLayout
android:id="#+id/dialog_custom_title_area"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingRight="10dp">
<TextView
android:id="#+id/custom_title" style="?android:attr/windowTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="#dimen/abs__alert_dialog_title_height"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:textColor="#ffffff"
android:gravity="center_vertical|left" />
<ImageButton
android:id="#+id/ok_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="#dimen/abs__action_button_min_width"
android:minHeight="#dimen/abs__alert_dialog_title_height"
android:scaleType="center"
android:src="#drawable/ic_action_accept"
android:background="#drawable/abs__item_background_holo_dark"
android:visibility="visible"
android:layout_gravity="center_vertical"
android:contentDescription="#string/acc_done"/>
<ImageButton
android:id="#+id/cancel_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="#dimen/abs__action_button_min_width"
android:minHeight="#dimen/abs__alert_dialog_title_height"
android:scaleType="center"
android:src="#drawable/ic_action_cancel"
android:background="#drawable/abs__item_background_holo_dark"
android:visibility="visible"
android:layout_gravity="center_vertical"
android:contentDescription="#string/acc_cancel"
/>
</LinearLayout>
<View
android:id="#+id/dialog_title_divider"
android:layout_width="fill_parent"
android:layout_height="2dip"
android:background="#color/abs__holo_blue_light" />
</LinearLayout>
<RelativeLayout
android:id="#+id/list_suggestions_layout"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<!-- this is where the main dialog area is laid out -->
</RelativeLayout>
</LinearLayout>
And finally, in my AndroidManifext.xml, here is how I define my TagActivity:
<activity
android:icon="#drawable/ic_home"
android:name=".activity.TagActivity"
android:theme="#style/Theme.Sherlock.Dialog"/>
OK, maybe it is not the super perfect solution and maybe it is a bad solution, but I tried this on android 2.3.7 and android 4.1.2:
2.3.7 (real device)
4.1.2 (emulator)
We start by creating a dialog Title style to make sure we have some space for our icons:
res/values/dialogstyles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Dialog" parent="#android:style/Theme.Dialog">
<item name="android:windowTitleStyle">#style/MyOwnDialogTitle</item>
</style>
<style name="MyOwnDialogTitle">
<!-- we need to make sure our images fit -->
<item name="android:layout_marginRight">100dp</item>
</style>
</resources>
res/values-v11/dialogstyles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Dialog" parent="#android:style/Theme.Holo.Dialog">
<item name="android:windowTitleStyle">#style/MyOwnDialogTitle</item>
</style>
</resources>
Then we create our DialogFragment with two tricks:
set the style in the onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.Dialog);
}
override onCreateView and add our layout (of buttons) to the Dialog (see comments)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//we need the view to remove the tree observer (that's why it is final)
final View view = inflater.inflate(R.layout.dialog_custom, container);
getDialog().setTitle("Shush Dialog");
//register a layout listener to add our buttons
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
//inflate our buttons
View menu = LayoutInflater.from(getActivity()).inflate(R.layout.layout_mymenu, null);
//get the root view of the Dialog (I am pretty sure this is the weakest link)
FrameLayout fl = ((FrameLayout) getDialog().getWindow().getDecorView());
//get the height of the root view (to estimate the height of the title)
int height = fl.getHeight() - fl.getPaddingTop() - fl.getPaddingBottom();
//to estimate the height of the title, we subtract our view's height
//we are sure we have the heights btw because layout is done
height = height - view.getHeight();
//prepare the layout params for our view (this includes setting its width)
//setting the height is not necessary if we ensure it is small
//we could even add some padding but anyway!
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, height);
params.gravity = Gravity.RIGHT | Gravity.TOP;
//add the view and we are done
fl.addView(menu, params);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
return view;
}
Alright if it just images, then you just have ensure that everything that you create in xml is scaled by density pixels or DP for short. Most simple coding that sets paint are usually set by pixels as well and may need a manual coding version to density pixels.

Android Image Dialog/Popup

Is it possible to have just an image popup/come-up in an Android application? It's similar to an overriding the normal view of an AlertDialog so that it contains just an image and nothing else.
SOLUTION: I was able to find an answer thanks to #blessenm's help. Masking an activity as a dialog seems to be the ideal way. The following is the code that I have used. This dialog styled activity can be invoked as needed by the application the same way a new activity would be started
ImageDialog.java
public class ImageDialog extends Activity {
private ImageView mDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_dialog_layout);
mDialog = (ImageView)findViewById(R.id.your_image);
mDialog.setClickable(true);
//finish the activity (dismiss the image dialog) if the user clicks
//anywhere on the image
mDialog.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
}
your_dialog_layout.xml
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image_dialog_root"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:gravity = "center">
<ImageView
android:id="#+id/your_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src = "#drawable/your_image_drawable"/>
</FrameLayout>
It is crucial that you set the following style for the activity to accomplish this:
styles.xml
<style name="myDialogTheme" parent="#android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFrame">#null</item>
<item name="android:background">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowContentOverlay">#null</item>
</style>
The final step is to declare this style for the activity in the manifest as follows:
<activity android:name=".ImageDialog" android:theme="#style/myDialogTheme" />
No xml:
public void showImage() {
Dialog builder = new Dialog(this);
builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
builder.getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
//nothing;
}
});
ImageView imageView = new ImageView(this);
imageView.setImageURI(imageUri);
builder.addContentView(imageView, new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
builder.show();
}
If you just want to use a normal dialog something like this should work
Dialog settingsDialog = new Dialog(this);
settingsDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
settingsDialog.setContentView(getLayoutInflater().inflate(R.layout.image_layout
, null));
settingsDialog.show();
image_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:src="YOUR IMAGE"/>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="OK" android:onClick="dismissListener"/>
</LinearLayout>
Try the following:
It has image zoom_in/zoom_out as well.
Step 1:
Add compile 'com.github.chrisbanes.photoview:library:1.2.4' to your build.gradle
Step 2:
Add the following xml
custom_fullimage_dialoge.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_root" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:padding="10dp">
<ImageView android:id="#+id/fullimage" android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ImageView>
<TextView android:id="#+id/custom_fullimage_placename"
android:layout_width="wrap_content" android:layout_height="fill_parent"
android:textColor="#FFF">
</TextView>
</LinearLayout>
Step 3:
private void loadPhoto(ImageView imageView, int width, int height) {
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
//dialog.setContentView(R.layout.custom_fullimage_dialog);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_fullimage_dialog,
(ViewGroup) findViewById(R.id.layout_root));
ImageView image = (ImageView) layout.findViewById(R.id.fullimage);
image.setImageDrawable(imageView.getDrawable());
image.getLayoutParams().height = height;
image.getLayoutParams().width = width;
mAttacher = new PhotoViewAttacher(image);
image.requestLayout();
dialog.setContentView(layout);
dialog.show();
}
Step 4:
user_Image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
loadPhoto(user_Image,width,height);
}
});
You can do it easily by create a Dialog Fragment in Kotlin:
BigImageDialog.kt
class BigImageDialog():DialogFragment() {
private var imageUrl = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
imageUrl = arguments.getString("url")
}
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View {
val v = inflater!!.inflate(R.layout.dialog_big_image, container, false)
this.dialog.window.requestFeature(Window.FEATURE_NO_TITLE)
Picasso.get().load(imageUrl).into(v.bigImageView)
return v
}
override fun onStart() {
super.onStart()
val dialog = dialog
if (dialog != null) {
dialog.window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}
}
companion object {
#JvmStatic
fun newInstance(imageUrl: String) =
BigImageDialog().apply {
arguments = Bundle().apply {
putString("url", imageUrl)
}
}
}
}
dialog_big_image.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/bigImageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Opening Dialog:
"smallImageView".setOnClickListener { BigImageDialog.newInstance("image url").show(fragmentManager,"") }
There is a couple ways you can do this. But, if you're looking to have your image appear to be floating above your existing activity, you may want to use an activity with android:theme="#style/Theme.Transparent" defined in the manifest. Then, design your layout to just have a single ImageView positioned in the center of the screen. The user will have to push the back button to get out of this, but it sounds like that's what you want.
If you want it to look like an actual dialog, you can always use a dialog styled activity as well using Theme.Dialog. OR, you could just use a dialog and customize it.
The more flexible and recommended way is use DialogFragment. If you want to support versions before 3.0 you can use compatibility library

Categories

Resources