mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-29 21:51:04 +00:00
fix: Add scrollable content to modern style settings dialogs (#5211)
This commit is contained in:
@@ -42,6 +42,7 @@ import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.Toolbar;
|
||||
@@ -773,16 +774,15 @@ public class Utils {
|
||||
Dialog dialog = new Dialog(context);
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); // Remove default title bar.
|
||||
|
||||
// Create main layout.
|
||||
LinearLayout mainLayout = new LinearLayout(context);
|
||||
mainLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
// Preset size constants.
|
||||
final int dip4 = dipToPixels(4);
|
||||
final int dip8 = dipToPixels(8);
|
||||
final int dip16 = dipToPixels(16);
|
||||
final int dip24 = dipToPixels(24);
|
||||
|
||||
// Create main layout.
|
||||
LinearLayout mainLayout = new LinearLayout(context);
|
||||
mainLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
mainLayout.setPadding(dip24, dip16, dip24, dip24);
|
||||
// Set rounded rectangle background.
|
||||
ShapeDrawable mainBackground = new ShapeDrawable(new RoundRectShape(
|
||||
@@ -802,55 +802,71 @@ public class Utils {
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
layoutParams.setMargins(0, 0, 0, dip8);
|
||||
layoutParams.setMargins(0, 0, 0, dip16);
|
||||
titleView.setLayoutParams(layoutParams);
|
||||
mainLayout.addView(titleView);
|
||||
}
|
||||
|
||||
// Message (if not replaced by EditText).
|
||||
if (editText == null && message != null) {
|
||||
TextView messageView = new TextView(context);
|
||||
messageView.setText(message); // Supports Spanned (HTML).
|
||||
messageView.setTextSize(16);
|
||||
messageView.setTextColor(getAppForegroundColor());
|
||||
// Enable HTML link clicking if the message contains links.
|
||||
if (message instanceof Spanned) {
|
||||
messageView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
// Create content container (message/EditText) inside a ScrollView only if message or editText is provided.
|
||||
ScrollView contentScrollView = null;
|
||||
LinearLayout contentContainer = null;
|
||||
if (message != null || editText != null) {
|
||||
contentScrollView = new ScrollView(context);
|
||||
contentScrollView.setVerticalScrollBarEnabled(false); // Disable the vertical scrollbar.
|
||||
contentScrollView.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||
if (editText != null) {
|
||||
ShapeDrawable scrollViewBackground = new ShapeDrawable(new RoundRectShape(
|
||||
createCornerRadii(10), null, null));
|
||||
scrollViewBackground.getPaint().setColor(getEditTextBackground());
|
||||
contentScrollView.setPadding(dip8, dip8, dip8, dip8);
|
||||
contentScrollView.setBackground(scrollViewBackground);
|
||||
contentScrollView.setClipToOutline(true);
|
||||
}
|
||||
LinearLayout.LayoutParams messageParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams contentParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
0,
|
||||
1.0f // Weight to take available space.
|
||||
);
|
||||
messageParams.setMargins(0, dip8, 0, dip16);
|
||||
messageView.setLayoutParams(messageParams);
|
||||
mainLayout.addView(messageView);
|
||||
}
|
||||
contentScrollView.setLayoutParams(contentParams);
|
||||
contentContainer = new LinearLayout(context);
|
||||
contentContainer.setOrientation(LinearLayout.VERTICAL);
|
||||
contentScrollView.addView(contentContainer);
|
||||
|
||||
// EditText (if provided).
|
||||
if (editText != null) {
|
||||
// Remove EditText from its current parent, if any.
|
||||
ViewGroup parent = (ViewGroup) editText.getParent();
|
||||
if (parent != null) {
|
||||
parent.removeView(editText);
|
||||
// Message (if not replaced by EditText).
|
||||
if (editText == null && message != null) {
|
||||
TextView messageView = new TextView(context);
|
||||
messageView.setText(message); // Supports Spanned (HTML).
|
||||
messageView.setTextSize(16);
|
||||
messageView.setTextColor(getAppForegroundColor());
|
||||
// Enable HTML link clicking if the message contains links.
|
||||
if (message instanceof Spanned) {
|
||||
messageView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
LinearLayout.LayoutParams messageParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
messageView.setLayoutParams(messageParams);
|
||||
contentContainer.addView(messageView);
|
||||
}
|
||||
// Style the EditText to match the dialog theme.
|
||||
editText.setTextColor(getAppForegroundColor());
|
||||
editText.setBackgroundColor(isDarkModeEnabled() ? Color.BLACK : Color.WHITE);
|
||||
editText.setPadding(dip8, dip8, dip8, dip8);
|
||||
ShapeDrawable editTextBackground = new ShapeDrawable(new RoundRectShape(
|
||||
createCornerRadii(10), null, null));
|
||||
editTextBackground.getPaint().setColor(getEditTextBackground()); // Background color for EditText.
|
||||
editText.setBackground(editTextBackground);
|
||||
|
||||
LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
editTextParams.setMargins(0, dip8, 0, dip16);
|
||||
// Prevent buttons from moving off the screen by fixing the height of the EditText.
|
||||
final int maxHeight = (int) (context.getResources().getDisplayMetrics().heightPixels * 0.6);
|
||||
editText.setMaxHeight(maxHeight);
|
||||
mainLayout.addView(editText, 1, editTextParams);
|
||||
// EditText (if provided).
|
||||
if (editText != null) {
|
||||
// Remove EditText from its current parent, if any.
|
||||
ViewGroup parent = (ViewGroup) editText.getParent();
|
||||
if (parent != null) {
|
||||
parent.removeView(editText);
|
||||
}
|
||||
// Style the EditText to match the dialog theme.
|
||||
editText.setTextColor(getAppForegroundColor());
|
||||
editText.setBackgroundColor(Color.TRANSPARENT);
|
||||
editText.setPadding(0, 0, 0, 0);
|
||||
LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
contentContainer.addView(editText, editTextParams);
|
||||
}
|
||||
}
|
||||
|
||||
// Button container.
|
||||
@@ -861,7 +877,7 @@ public class Utils {
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
buttonContainerParams.setMargins(0, dip8, 0, 0);
|
||||
buttonContainerParams.setMargins(0, dip16, 0, 0);
|
||||
buttonContainer.setLayoutParams(buttonContainerParams);
|
||||
|
||||
// Lists to track buttons.
|
||||
@@ -1036,25 +1052,29 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
// Add ScrollView to main layout only if content exist.
|
||||
if (contentScrollView != null) {
|
||||
mainLayout.addView(contentScrollView);
|
||||
}
|
||||
mainLayout.addView(buttonContainer);
|
||||
dialog.setContentView(mainLayout);
|
||||
|
||||
// Set dialog window attributes.
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
setDialogWindowParameters(context, window);
|
||||
setDialogWindowParameters(window);
|
||||
}
|
||||
|
||||
return new Pair<>(dialog, mainLayout);
|
||||
}
|
||||
|
||||
public static void setDialogWindowParameters(Context context, Window window) {
|
||||
public static void setDialogWindowParameters(Window window) {
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
|
||||
Resources resources = context.getResources();
|
||||
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
|
||||
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
|
||||
int portraitWidth = (int) (displayMetrics.widthPixels * 0.9);
|
||||
if (resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
|
||||
if (Resources.getSystem().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
portraitWidth = (int) Math.min(portraitWidth, displayMetrics.heightPixels * 0.9);
|
||||
}
|
||||
params.width = portraitWidth;
|
||||
@@ -1199,7 +1219,7 @@ public class Utils {
|
||||
return darkColor == Color.BLACK
|
||||
// Lighten the background a little if using AMOLED dark theme
|
||||
// as the dialogs are almost invisible.
|
||||
? 0xFF0D0D0D
|
||||
? 0xFF080808 // 3%
|
||||
: darkColor;
|
||||
}
|
||||
return getThemeLightColor();
|
||||
|
||||
@@ -129,8 +129,7 @@ abstract class Check {
|
||||
ImageView iconView = new ImageView(activity);
|
||||
iconView.setImageResource(Utils.getResourceIdentifier("revanced_ic_dialog_alert", "drawable"));
|
||||
iconView.setColorFilter(Utils.getAppForegroundColor(), PorterDuff.Mode.SRC_IN);
|
||||
final int dip8 = dipToPixels(8);
|
||||
iconView.setPadding(0, dip8, 0, dip8);
|
||||
iconView.setPadding(0, 0, 0, 0);
|
||||
LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
|
||||
@@ -24,10 +24,7 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.*;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
|
||||
@@ -298,7 +295,6 @@ public class ColorPickerPreference extends EditTextPreference {
|
||||
// Horizontal layout for preview and EditText.
|
||||
LinearLayout inputLayout = new LinearLayout(context);
|
||||
inputLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
inputLayout.setPadding(0, 0, 0, dipToPixels(10));
|
||||
|
||||
dialogColorPreview = new TextView(context);
|
||||
LinearLayout.LayoutParams previewParams = new LinearLayout.LayoutParams(
|
||||
@@ -338,11 +334,23 @@ public class ColorPickerPreference extends EditTextPreference {
|
||||
paddingView.setLayoutParams(params);
|
||||
inputLayout.addView(paddingView);
|
||||
|
||||
// Create main container for color picker and input layout.
|
||||
LinearLayout container = new LinearLayout(context);
|
||||
container.setOrientation(LinearLayout.VERTICAL);
|
||||
container.addView(colorPicker);
|
||||
container.addView(inputLayout);
|
||||
// Create content container for color picker and input layout.
|
||||
LinearLayout contentContainer = new LinearLayout(context);
|
||||
contentContainer.setOrientation(LinearLayout.VERTICAL);
|
||||
contentContainer.addView(colorPicker);
|
||||
contentContainer.addView(inputLayout);
|
||||
|
||||
// Create ScrollView to wrap the content container.
|
||||
ScrollView contentScrollView = new ScrollView(context);
|
||||
contentScrollView.setVerticalScrollBarEnabled(false); // Disable vertical scrollbar.
|
||||
contentScrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); // Disable overscroll effect.
|
||||
LinearLayout.LayoutParams scrollViewParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
0,
|
||||
1.0f
|
||||
);
|
||||
contentScrollView.setLayoutParams(scrollViewParams);
|
||||
contentScrollView.addView(contentContainer);
|
||||
|
||||
// Create custom dialog.
|
||||
final int originalColor = currentColor & 0x00FFFFFF;
|
||||
@@ -391,9 +399,9 @@ public class ColorPickerPreference extends EditTextPreference {
|
||||
false // Do not dismiss dialog when onNeutralClick.
|
||||
);
|
||||
|
||||
// Add the custom container to the dialog's main layout.
|
||||
// Add the ScrollView to the dialog's main layout.
|
||||
LinearLayout dialogMainLayout = dialogPair.second;
|
||||
dialogMainLayout.addView(container, 1);
|
||||
dialogMainLayout.addView(contentScrollView, dialogMainLayout.getChildCount() - 1);
|
||||
|
||||
// Set up color picker listener with debouncing.
|
||||
// Add listener last to prevent callbacks from set calls above.
|
||||
|
||||
@@ -11,11 +11,7 @@ import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.*;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -107,14 +103,16 @@ public class CustomDialogListPreference extends ListPreference {
|
||||
|
||||
@Override
|
||||
protected void showDialog(Bundle state) {
|
||||
Context context = getContext();
|
||||
|
||||
// Create ListView.
|
||||
ListView listView = new ListView(getContext());
|
||||
ListView listView = new ListView(context);
|
||||
listView.setId(android.R.id.list);
|
||||
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||||
|
||||
// Create custom adapter for the ListView.
|
||||
ListPreferenceArrayAdapter adapter = new ListPreferenceArrayAdapter(
|
||||
getContext(),
|
||||
context,
|
||||
Utils.getResourceIdentifier("revanced_custom_list_item_checked", "layout"),
|
||||
getEntries(),
|
||||
getEntryValues(),
|
||||
@@ -137,7 +135,7 @@ public class CustomDialogListPreference extends ListPreference {
|
||||
|
||||
// Create the custom dialog without OK button.
|
||||
Pair<Dialog, LinearLayout> dialogPair = Utils.createCustomDialog(
|
||||
getContext(),
|
||||
context,
|
||||
getTitle() != null ? getTitle().toString() : "",
|
||||
null,
|
||||
null,
|
||||
@@ -149,35 +147,13 @@ public class CustomDialogListPreference extends ListPreference {
|
||||
true
|
||||
);
|
||||
|
||||
Dialog dialog = dialogPair.first;
|
||||
// Add the ListView to the main layout.
|
||||
LinearLayout mainLayout = dialogPair.second;
|
||||
|
||||
// Measure content height before adding ListView to layout.
|
||||
// Otherwise, the ListView will push the buttons off the screen.
|
||||
int totalHeight = 0;
|
||||
int widthSpec = View.MeasureSpec.makeMeasureSpec(
|
||||
getContext().getResources().getDisplayMetrics().widthPixels,
|
||||
View.MeasureSpec.AT_MOST
|
||||
);
|
||||
int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
|
||||
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
View listItem = adapter.getView(i, null, listView);
|
||||
listItem.measure(widthSpec, heightSpec);
|
||||
totalHeight += listItem.getMeasuredHeight();
|
||||
}
|
||||
|
||||
// Cap the height at maxHeight.
|
||||
int maxHeight = (int) (getContext().getResources().getDisplayMetrics().heightPixels * 0.6);
|
||||
int finalHeight = Math.min(totalHeight, maxHeight);
|
||||
|
||||
// Add ListView to the main layout with calculated height.
|
||||
LinearLayout.LayoutParams listViewParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
finalHeight // Use calculated height directly.
|
||||
0,
|
||||
1.0f
|
||||
);
|
||||
final int marginHorizontal = dipToPixels(8);
|
||||
listViewParams.setMargins(0, marginHorizontal, 0, marginHorizontal);
|
||||
mainLayout.addView(listView, mainLayout.getChildCount() - 1, listViewParams);
|
||||
|
||||
// Handle item click to select value and dismiss dialog.
|
||||
@@ -188,10 +164,10 @@ public class CustomDialogListPreference extends ListPreference {
|
||||
adapter.setSelectedValue(selectedValue);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
dialog.dismiss();
|
||||
dialogPair.first.dismiss();
|
||||
});
|
||||
|
||||
// Show the dialog.
|
||||
dialog.show();
|
||||
dialogPair.first.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
@@ -216,6 +217,8 @@ class WebViewDialog extends Dialog {
|
||||
|
||||
// Create WebView.
|
||||
WebView webView = new WebView(getContext());
|
||||
webView.setVerticalScrollBarEnabled(false); // Disable the vertical scrollbar.
|
||||
webView.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||
webView.getSettings().setJavaScriptEnabled(true);
|
||||
webView.setWebViewClient(new OpenLinksExternallyWebClient());
|
||||
webView.loadDataWithBaseURL(null, htmlContent, "text/html", "utf-8", null);
|
||||
@@ -228,7 +231,7 @@ class WebViewDialog extends Dialog {
|
||||
// Set dialog window attributes
|
||||
Window window = getWindow();
|
||||
if (window != null) {
|
||||
Utils.setDialogWindowParameters(getContext(), window);
|
||||
Utils.setDialogWindowParameters(window);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user