I've implemented a long click listener to delete an entry from my recyclerview and I'd like to give the user one last chance to change their mind. I've done something similar in a 'standard' view using an Alert Dialog and i've made a few drawables for the buttons in the alert view that I would like to use again (to keep a constant interface among all my views)
The drawable I'm using is:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/minus_button"
android:state_pressed="false"
android:state_selected="false"/>
<item android:drawable="#drawable/add_button"
android:state_pressed="true"/>
</selector>
The alert I'm trying to use is :
public void deleteRequestCheck(final int tempIDval){
AlertDialog.Builder builder = new AlertDialog.Builder(this.context);
builder.setMessage("Are you sure you want to reset all your climbs back to zero?");
builder.setCancelable(false);
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteEntry(tempIDval);
}
});
AlertDialog alert = builder.create();
alert.show();
Button nbutton = alert.getButton(DialogInterface.BUTTON_NEGATIVE);
nbutton.setBackgroundColor(getDrawable(R.drawable.button_tap));
nbutton.setTextColor(Color.WHITE);
Button pbutton = alert.getButton(DialogInterface.BUTTON_POSITIVE);
pbutton.setBackgroundColor(getDrawable(R.drawable.button_tap));
pbutton.setTextColor(Color.WHITE);
}
and I'm calling this from inside my Adapter class (where the longclick action is handled).
The issue I'm having is that
nbutton.setBackgroundColor(getDrawable(R.drawable.button_tap));
pbutton.setBackgroundColor(getDrawable(R.drawable.button_tap));
are giving me an error that it Cannot resolve method 'getDrawable(int)'. This has me stumped as this is identical to how I've created and called this alert dialog in my previous activities.
There are actually 2 ways you can do this:
1) Programmatically like:
nbutton.setBackground(ContextCompat.getDrawable(this.context, R.drawable.mypositiveButtonDrawable));
But what if you want same button color for other dialogs? Why to duplicate the effort?
2) through styles.xml
Create a theme in your styles.xml like:
<style name="DiscardChangesDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="buttonBarNegativeButtonStyle">#style/DialogButtonNegative</item>
<item name="buttonBarPositiveButtonStyle">#style/DialogButtonPositive</item>
</style>
<style name="DialogButtonNegative" parent="Widget.AppCompat.Button.Borderless">
<item name="android:textColor">#color/dialog_button_negative</item>
</style>
<style name="DialogButtonPositive" parent="Widget.AppCompat.Button.Borderless">
<item name="android:textColor">#color/dialog_button_positive</item>
</style>
and then use it like:
AlertDialog.Builder(this, R.style.DiscardChangesDialog)
and then you do not need to worry about adapter or anything.
Hope it helps!!!
Related
This question already has answers here:
Prevent Android activity dialog from closing on outside touch
(20 answers)
Closed 2 years ago.
i have an AlertDialog on my Android app. When i show to AlertDialog i want to disable only when users click "OKAY" button. Because i reset the screen when users clicked "OKAY" button.
My problem is when i click somewhere on screen outside of AlertDialog, dialog is closing but i can not clean the screen.
This is my code;
AlertDialog.Builder builder = new AlertDialog.Builder(GameOnePlayer.this, R.style.AlertDialogTheme);
//builder.setCancelable(true);
View view = LayoutInflater.from(GameOnePlayer.this).inflate(
R.layout.layout_winner_dialog,
(ConstraintLayout)findViewById(R.id.layoutAlertDialogContainer)
);
builder.setView(view);
final AlertDialog alertDialog = builder.create();
//alertDialog.setCanceledOnTouchOutside(false);
view.findViewById(R.id.buttonAlertDialog).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hideSystemUI();
clearScreen();
alertDialog.dismiss();
}
});
if(alertDialog.getWindow() != null){
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(0));
}
alertDialog.show();
I tried alertDialog.setCanceledOnTouchOutside(false); but it did'not work.
<style name="AlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
This is my style.xml
What do I have to do for this? Thanks.
Edit: I tried these advices but did not work.
builder.setCancelable(false);
alertDialog.setCancelable(false);
alertDialog.setCanceledOnTouchOutside(false);
Edit2:
Hi i found the solution on the other post.
Just added these line in the onCreate method.
this.setFinishOnTouchOutside(false);
Many thanks for all you helpers.
alertDialog.setCancelable(false);
alertDialog.setCanceledOnTouchOutside(false);
builder.setCancelable(false)
Put this line below the "builder.setView(view)" line so your dialog is not close when you touch outside the dialog or when you press back button your dialog is not closed.
You can add OnCancelListener to your dialog to listen Dialog cancellation and perform the screen reset.
builder.setOnCancelListener {
//call your method to reset the screen
}
Like the title, I am wondering how to get rid of the green bar at the top so that it matches the background of the activity. I have no idea where to look I've had a look in the manifest and haven't found anything.
What do I do so that it matches the background of the activity?
Note. Different activities have different backgrounds, so is there a way that I just match the activity it is on?
The green bar is called Status bar, and to hide it in activity call below method in onCreate()
void hideStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
getWindow().getDecorView().setSystemUiVisibility(uiOptions);
} else {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
And to hide it in a fragment, call it in onCreateView()
void hideStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
requireActivity().getWindow().getDecorView().setSystemUiVisibility(uiOptions);
} else {
requireActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
You can change status bar color using this extension function, call this function from Activity just passing the color
fun AppCompatActivity.changeStatusBarColor(#ColorRes color: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = ContextCompat.getColor(this, color)
}
}
go to following path:
app->res->values->styles
and here in style tag three item tags are available, in that colour of first and last item keep same.
then app status bar and action bar colour display same.
Example:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here.
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
-->
<item name="colorPrimary">#FFA500</item>
<item name="colorPrimaryDark">#FFA500</item>
</style>
This question already has an answer here:
Dialog opens blank
(1 answer)
Closed 5 years ago.
I'm trying to make an AlertDialog in onCreateView() inside a Fragment. Here's the code I'm using:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()));
builder.setTitle("blah blah blah");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//do something
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
getActivity().onBackPressed();
}
});
builder.create().show();
But whenever this executes, I get a completely white dialog where nothing is visible. If I click around the box, I eventually find where the positive button is because the code in setPositiveButton's OnClickListener gets executed. Here's a screenshot:
As you can see, the rest of my app is in the background and I'm left with a useless dialog box. I've tried changing the theme, but that hasn't made any difference. I can't seem to find anyone else with this problem, so any information as to why this is happening is greatly appreciated!
Try this
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertStyle);
Add in Style.xml file
<style name="AlertStyle" parent="Theme.AppCompat.Light.Dialog">
<item name="android:colorAccent">#f3f3f3</item>
<item name="android:textColor">#f3f3f3</item>
<item name="android:textColorPrimary">#f3f3f3</item>
</style>
Remove the create() method from the builder.create().show() like that
builder.show();
Try this for all version
AlertDialog.Builder builder;
if(Build.VERSION.SDK_INT >= 21)
builder = new AlertDialog.Builder(this, android.R.style.Theme_Material_Light_Dialog_Alert);
else
builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setTitle("title");
builder.setMessage("Message");
builder.create().show();
Question
How does one programatically (without touching the AndroidManifext.xml) set the theme of an Activity so that it looks like a dialog?
Note: I am ok with modifying the AndroidManifext.xml as long as it does not need to be modified in order to switch between making it look like a normal activity or a dialog.
What I've tried so far
I tried the following as per this stackoverflow answer:
public class DialogActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
setTheme(android.R.style.Theme_DeviceDefault_Dialog);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog);
Log.d(TAG,"Build.VERSION.SDK_INT: "+Build.VERSION.SDK_INT); // 23
}
}
But it ends up blacking out everything in the background.
I also saw this stackoverflow answer, and tried:
public class DialogActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
setTheme(android.R.style.Theme_DeviceDefault_Dialog);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog);
getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
}
}
but it ends up making everything black.
What do? Thank you.
Background
The Activity behind an Acivity is drawn if the foreground activity's theme according to its AndroidManifest.xml is a dialog; otherwise the android os will not draw the Activity behind it (probably to save memory since it usually won't be seen anyway).
To exploit this, we set the theme of our Acitvity to a dialog in the manifest, making the android os draw the Activity behind it, but later, programatically set our Activity's theme to whatever we like at runtime.
Example on github
I made an example and put it on github.
Tutorial
Step 1: create two custom themes for your application in styles.xml. One for normal activities, and another for dialog activities. It is important for the custom dialog theme to inherit from a base theme that is also a dialog. In my case, the parent theme is Base.Theme.AppCompat.Light.Dialog.FixedSize). Here is my styles.xml:
<resources>
<!-- custom normal activity theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>
<!-- custom dialog activity theme -->
<style name="AppTheme.Dialog" parent="Base.Theme.AppCompat.Light.Dialog.FixedSize">
<!-- removing the dialog's action bar -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>
Step 2: in the AndroidManifest.xml, set the theme of the Activity in question to any dialog theme. This makes the android os think that the Activity is a dialog, so it will draw the Activity behind it, and not black it out. In my case, I used Theme.AppCompat.Dialog. Below is my AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.eric.questiondialog_artifact">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name">
<activity
android:name=".DialogActivity"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Dialog"> <-- IMPORTANT!!! -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Step 3: in the actual activity, set the theme programatically to either the theme for normal activities, or the theme for dialogs. My DialogActivity.java is below:
package com.example.eric.questiondialog_artifact;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
public class DialogActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
setTheme(R.style.AppTheme_Dialog); // can either use R.style.AppTheme_Dialog or R.style.AppTheme as deined in styles.xml
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog);
}
}
if what you're looking for is just a theme with transparent background for you activity, just use this:
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
apply this style to your activity in your AndroidManifest file and this is it
I am late but still for future users
you need to call the below code after setTheme() Calling this allows the Activity behind this one to be seen again. Once all such Activities have been redrawn
// setTheme()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
Method getActivityOptions = Activity.class.getDeclaredMethod("getActivityOptions");
getActivityOptions.setAccessible(true);
Object options = getActivityOptions.invoke(activity);
Class<?>[] classes = Activity.class.getDeclaredClasses();
Class<?> translucentConversionListenerClazz = null;
for (Class clazz : classes) {
if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
translucentConversionListenerClazz = clazz;
}
}
Method convertToTranslucent = Activity.class.getDeclaredMethod("convertToTranslucent",
translucentConversionListenerClazz, ActivityOptions.class);
convertToTranslucent.setAccessible(true);
convertToTranslucent.invoke(activity, null, options);
} catch (Throwable t) {
}
} else {
try {
Class<?>[] classes = Activity.class.getDeclaredClasses();
Class<?> translucentConversionListenerClazz = null;
for (Class clazz : classes) {
if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
translucentConversionListenerClazz = clazz;
}
}
Method method = Activity.class.getDeclaredMethod("convertToTranslucent",
translucentConversionListenerClazz);
method.setAccessible(true);
method.invoke(activity, new Object[] {
null
});
} catch (Throwable t) {
}
}
Try these code before dailog.setMessage(...);
Dialog id = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_DARK);
Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
//Default theme
Try this for Old theme
Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_TRADITIONAL);
Try these for KITKAT theme
Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_DARK); //Dark
Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_LIGHT);
Try these codes for Pragmatically
Exmaple
dialog = new AlertDialog.Builder(this);
dialog = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_DARK);
dialog.setTitle("HAI");
dialog.setMessage("look");
dialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
Toast toast= Toast.makeText(getApplicationContext(), "This is exmaple theme", Toast.LENGTH_LONG);
Before Clicking:
After Clicking:
I am having an issue with my code where clicking on an actionbar action will bring up the title of the action. If you then click on the title that is how you get to the onclick listener. Very strange... I know it is hard to tell without code but I am away and will post it soon. Just wanted to ask around to see if anyone has experienced similar.
ActionBar:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_settings"
android:title="#string/hello1"
app:showAsAction="never"/>
</menu>
onClickListener:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_settings:
onCreateDialog();
return true;
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
public void onCreateDialog() {
String[] string= new String[]{"Add to Calendar", "Share"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Options")
.setItems(string, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:...................}
This is the expected behavior for the way you have the menu setup currently.
<item
android:id="#+id/action_settings"
android:title="#string/hello1"
app:showAsAction="never"/> <!-- Don't show this action until the overflow menu is shown -->
With the showAsAction set to never, the action is not shown until the overflow menu is shown. The available options for showAsAction are:
["ifRoom" | "never" | "withText" | "always" | "collapseActionView"]
In your case, because you only have one menu item, you can use always.
Refer to the menu resource documentation for more info.
You should be able to preview this in Android Studio (see screenshot below)
I fixed it by extending the activity to appcompatactivity instead of activity. Weird bug. Then it didn't do it.