I created a custom dialog preference in my Android application, but I can not figure out how to get the dialog which is displayed to span the complete width of the display.
image of dialog with too much space on left and right side
I found many proposed solutions to get a normal Dialog in full screen mode
Android get full width for custom Dialog
https://gist.github.com/koocbor/88db64192638bff09aa4
http://blog.jimbaca.com/force-dialog-to-take-up-full-screen-width/
But setting the attributes via getWindow does not work:
#Override
public Dialog getDialog() {
Dialog dialog = super.getDialog();
dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
// or
// dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
return dialog;
}
And applying a full screen theme to my dialogs root element didn't do the job neither:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
[...]
android:theme="#style/FullscreenTheme">
Moreover I'm not able to access the onCreate Method (at least I don't know how) of the Dialog, to set the style there.
Did anyone had the same problem and figured out a solution for this very specific issue?
My layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:padding="0dp"
android:paddingTop="#dimen/preferences_dialog_def_padding"
android:paddingBottom="#dimen/preferences_dialog_def_padding">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="-2dp"
android:background="#color/expandable_preference_divider"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/preferences_expandable_margin_top_bottom"
android:layout_marginTop="#dimen/preferences_expandable_margin_top_bottom">
<RelativeLayout
android:id="#+id/icon_wrapper_choose"
android:layout_width="#dimen/preferences_expandable_icon_wrapper_size"
android:layout_height="#dimen/preferences_expandable_icon_wrapper_size"
android:layout_marginBottom="0dp"
android:layout_marginEnd="#dimen/preference_expandable_icon_margin"
android:layout_marginStart="#dimen/preference_expandable_icon_margin"
android:layout_marginTop="0dp"
android:gravity="center">
<ImageView
android:layout_width="#dimen/preferences_expandable_icon_size"
android:layout_height="#dimen/preferences_expandable_icon_size"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:cropToPadding="true"
android:scaleType="centerCrop"
android:src="#drawable/ic_settings_white_36dp"/>
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/icon_wrapper_choose"
android:paddingBottom="#dimen/preferences_expandable_text_padding_top_bottom"
android:paddingTop="#dimen/preferences_expandable_text_padding_top_bottom"
android:text="#string/pref_wheel_circumference_choose"
android:textColor="#color/colorAccent"
android:textSize="#dimen/text_size_medium"
android:textStyle="bold"/>
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_marginEnd="#dimen/preference_expandable_icon_margin"
android:layout_marginStart="#dimen/preference_expandable_icon_margin"
android:layout_height="wrap_content"
android:text="#string/etrto_hint"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingBottom="20dp"
android:paddingEnd="?android:attr/scrollbarSize"
android:layout_marginStart="#dimen/preference_expandable_icon_margin"
android:weightSum="3"
>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/etrto"/>
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="20dp"
android:paddingEnd="?android:attr/scrollbarSize"
android:layout_marginStart="#dimen/preference_expandable_icon_margin"
android:weightSum="3"
>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/manufacturer"/>
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="-2dp"
android:background="#color/expandable_preference_divider"/>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/preference_category_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:padding="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/preferences_expandable_margin_top_bottom"
android:layout_marginTop="#dimen/preferences_expandable_margin_top_bottom">
<RelativeLayout
android:id="#+id/icon_wrapper_manual"
android:layout_width="#dimen/preferences_expandable_icon_wrapper_size"
android:layout_height="#dimen/preferences_expandable_icon_wrapper_size"
android:layout_marginBottom="0dp"
android:layout_marginEnd="#dimen/preference_expandable_icon_margin"
android:layout_marginStart="#dimen/preference_expandable_icon_margin"
android:layout_marginTop="0dp"
android:gravity="center">
<ImageView
android:id="#+android:id/icon"
android:layout_width="#dimen/preferences_expandable_icon_size"
android:layout_height="#dimen/preferences_expandable_icon_size"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:cropToPadding="true"
android:scaleType="centerCrop"
android:src="#drawable/ic_edit_white_36dp"/>
</RelativeLayout>
<TextView
android:id="#+android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="#+id/icon_wrapper_manual"
android:paddingBottom="#dimen/preferences_expandable_text_padding_top_bottom"
android:paddingTop="#dimen/preferences_expandable_text_padding_top_bottom"
android:text="#string/pref_wheel_circumference_manually"
android:textColor="#color/colorAccent"
android:textSize="#dimen/text_size_medium"
android:textStyle="bold"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingBottom="20dp"
android:paddingEnd="?android:attr/scrollbarSize"
android:layout_marginStart="#dimen/preference_expandable_icon_margin"
android:weightSum="2.5"
>
<EditText
android:id="#+id/pref_dialog_wheelcircumference_et"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:textAlignment="textEnd"
android:textColor="#color/colorFont"
android:textSize="#dimen/text_size_small"
android:inputType="number"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:textAlignment="center"
android:text="#string/wheel_circumference_unit"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
My custom preference class
public class WheelCircumferencePreference extends android.preference.DialogPreference {
private static String TAG = "CustomSwitchPreference";
private int mWheelCircumference;
public static int WHEEL_CIRCUMFERENCE_DEFAULT = 2125;
private int mDialogLayoutResId = R.layout.pref_dialog_wheelcircumference;
public WheelCircumferencePreference(Context context) {
this(context, null);
}
public WheelCircumferencePreference(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.dialogPreferenceStyle);
}
public WheelCircumferencePreference(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
setLayoutResource(R.layout.custom_preference);
setDialogLayoutResource(mDialogLayoutResId);
setPositiveButtonText(getContext().getString(R.string.dialog_save));
setNegativeButtonText(getContext().getString(R.string.dialog_cancel));
}
#Override
protected Object onGetDefaultValue(TypedArray a, int index) {
// Default value from attribute. Fallback value is set to WHEEL_CIRCUMFERENCE_DEFAULT.
return a.getInteger(index, WHEEL_CIRCUMFERENCE_DEFAULT);
}
#Override
protected void onSetInitialValue(boolean restorePersistedValue,
Object defaultValue) {
would load value from shared preferences
if (restorePersistedValue) {
mWheelCircumference = getPersistedInt(WHEEL_CIRCUMFERENCE_DEFAULT);
} else {
mWheelCircumference = (Integer) defaultValue;
persistInt(mWheelCircumference);
}
}
private EditText mWheelCircumferenceEt;
#Override
protected void onBindDialogView(View view) {
mWheelCircumferenceEt = view.findViewById(R.id.pref_dialog_wheelcircumference_et);
if (mWheelCircumferenceEt == null) {
throw new IllegalStateException("preference dialog view must contain" +
" a EditText with id 'pref_dialog_wheelcircumference_et'");
}
mWheelCircumferenceEt.setText(Integer.toString(mWheelCircumference));
super.onBindDialogView(view);
}
#Override
public Dialog getDialog() {
//Dialog dialog = super.getDialog();
// WindowManager.LayoutParams p = getDialog().getWindow().getAttributes();
//p.height = LinearLayout.LayoutParams.WRAP_CONTENT;
//dialog.getWindow().setAttributes(p);
return dialog;
}
#Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
String circumferenceText = mWheelCircumferenceEt.getText().toString();
try {
mWheelCircumference = Integer.parseInt(circumferenceText);
} catch (Exception e) {
NLog.e(TAG, "onDialogClosed - ", e);
mWheelCircumference = WheelCircumferencePreference.WHEEL_CIRCUMFERENCE_DEFAULT;
}
persistInt(mWheelCircumference);
}
}
Edit:
Actually I only want the dialog to span over the full width of the screen, not the height. If I would use a additional PreferenceFragment (as the DialogPreference is already embedded in a PreferenceFragment ) the "Dialog" (aka Fragment) would take the complete width and height (i guess).
I already implemented a solution without a DialogPrefrence, that works but is not exactly elegant
using just a normal EditTextPreference
adding an onPreferenceClickListener to this preference in my SettingsFragment Code
the ClickListener displays a simple Dialog
Example:
Preference preference = findPreference(EXAMPLE_PREFRENCE);
if (preference != null) {
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
// showDialog();
}
});
But as I have a lot of preferences which will display dialogs the code for the dialog creation and display bloads the SettingsFragment and makes it nearly unreadable. Therefore I thought it would be a nice solution to put the responsibility of displaying the dialog and handling the preference values to the Preference and the XML layout.
Unfortunately I got stuck with the "full width issue" mentioned above.
Note: fixed the code of getDialog as I tested different versions (also in combination with the xml theme set)
Finally I did find a solution for this problem:
Fetch the AlertDialog of the Preference in showDialog method
#Override
protected void showDialog(Bundle state) {
super.showDialog(state);
CustomDialogPreference.makeDialogFullScreen((AlertDialog) getDialog());
}
make it span the complete width:
public static void makeDialogFullScreen(AlertDialog d) {
NLog.d(TAG, "makeDialogFullScreen enter ");
if (d != null) {
ViewGroup.LayoutParams params = d.getWindow().getAttributes();
if (params != null) {
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
d.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
}
}
}
Try this in the onResume of your dialog.
// Store access variables for window and blank point
Window window = getDialog().getWindow();
Point size = new Point();
// Store dimensions of the screen in `size`
Display display = window.getWindowManager().getDefaultDisplay();
display.getSize(size);
// Set the width of the dialog proportional to 75% of the screen width and height
window.setLayout((int) (size.x * 0.75), (int) (size.y * 0.75));
window.setGravity(Gravity.CENTER);
// Call super onResume after sizing
Adjust accordingly for 100%. It works great for a dialogFragment. Haven't tried it for your case though.
Wait, you're not looking for the bog-standard 'Pref settings user options appear in a dialog' thing are you? That's almost definitely already done in AndroidStudio's add activity...> Settings Activity in boiler plate, check it out, or look for sample settings apps
Anyway, I do actually have a fullscreen dialog in my app, although it purposely doesn't fill the full screen, and I actually use an activity with some fragments now instead.
Personally I think this is what your problem is, I remember having this exact issue when I first needed a dialog like this. You should just use activities and have up navigation (if you want a full screen "popup" type thing you could use the Navigation pattern that makes the home/up button an 'X' instead of a '<');
Or anything else, you don't need to have a dialog explicitly, and if you do then extend activity or dialog and get what you want.
Here's my activity stuff in case it's any use
my theme:
<style name="AppTheme.FullScreenDialog"
parent="#style/Theme.AppCompat.Light.Dialog">
<item name="windowActionBar">true</item>
<item name="windowNoTitle">true</item>
</style>
my onCreate gist:
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
...
requestWindowFeature(Window.FEATURE_NO_TITLE);
...
super.onCreate(savedInstanceState);
setContentView(getConcreteContentView());
ButterKnife.bind(this);
setUpUIComponents();
...
}
my general layout gist:
<CoordinatorLayout>
<AppBarLayout>
<android.support.v7.widget.Toolbar/>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="#+id/container_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:paddingTop="6dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:id="#+id/container_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tv_security_word"
android:paddingEnd="18dp"
android:paddingStart="18dp" />
<RelativeLayout
android:id="#+id/container_security"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="#+id/container_recycler"
android:minHeight="150dp"
android:paddingEnd="18dp"
android:paddingStart="18dp"
android:visibility="visible" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/security_container"
android:layout_centerHorizontal="true"
android:contentDescription="#string/app_name"
android:minHeight="50dp"
android:scaleType="centerInside" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Bon Chance!
Related
In these days i'm working on an app which is contain preference and i tried to put each preferences into a CardView. I can make a custom preference with old version of preference library but when i want to use CardView, I have to use preference library v7.
Screen Shot
As you can see, I made a preference category with CardView. Firstly I made a preference activity with a CardView which is contain a fragment. then i add my preference files in my ActivityPrefrences
public class ActivityPrefrences extends AppCompatActivity {
private int[] prefResId = {R.xml.app_preferences,R.xml.app_preferences};
private int[] fragmentResId = {R.id.fragmentGeneralSetting,R.id.fragmentRtl};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preference);
if (savedInstanceState == null) {
for(int i=0;i<prefResId.length;i++){
Fragment fragment = new PreferenceDataFragment();
Bundle bundle = new Bundle();
bundle.putInt("PREFERENCE_KEY", prefResId[i]);
fragment.setArguments(bundle);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(fragmentResId[i],fragment).commit();
}
}
}
Fragment Class:
public class PreferenceDataFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener{
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
//getPreferenceManager().setSharedPreferencesName("settings");
//getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE);
Bundle bundle = this.getArguments();
if (bundle != null) {
int resId = bundle.getInt("PREFERENCE_KEY", R.xml.app_preferences);
addPreferencesFromResource(resId);
}
}
}
activity_preference.xml
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarThumbVertical="#drawable/scrollbar_thumb"
android:scrollbarTrackVertical="#drawable/scrollbar_track"
android:clipToPadding="false"
android:duplicateParentState="false"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
app:cardElevation="6dp"
app:cardCornerRadius="6dp"
app:cardBackgroundColor="#android:color/white">
<FrameLayout
android:id="#+id/fragmentGeneralSetting"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
app:cardElevation="6dp"
app:cardCornerRadius="6dp"
app:cardBackgroundColor="#android:color/white">
<FrameLayout
android:id="#+id/fragmentRtl"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
Finally i added my own Custom preference in preference.xml but when i loading this activity on phone, i miss a part of view on screen. as you can see on above image, Gray area is holder and white are is a part of custom preference view.
Now i can't understand why my custom view not fitting in whole area of holder? and i can't use setSummary and setTitle in class, Actually "title" and "summary" not applied on TextViews, I don't know why?
This is my custom preference class
public class RTLCheckBoxPreference extends Preference {
private OnPreferenceClickListener prefListener;
private boolean currentValue = false;
public RTLCheckBoxPreference(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RTLCheckBoxPreference(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWidgetLayoutResource(R.layout.prefrence_checkbox);
}
#Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
super.onSetInitialValue(restorePersistedValue, defaultValue);
currentValue = restorePersistedValue ? getPersistedBoolean(false):(Boolean) defaultValue;
}
#Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setClickable(false);
holder.itemView.setPadding(0,0,0,0);
RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
param.setMargins(0,0,0,0);
holder.itemView.setLayoutParams(param);
}
}
This is my custom layout for my prefrence.
<FrameLayout 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:orientation="vertical"
android:minHeight="?attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:background="?attr/selectableItemBackground"
android:focusable="true" >
<com.bvapp.widget.HoloButton.HoloButton
android:id="#+id/btnCheckBoxPrefrence"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="15dip"
android:layout_marginTop="6dip">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:background="#drawable/check_box_outline_blank"
android:id="#+id/imgCheckBoxPrefrence"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"/>
<TextView android:id="#android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/text_main"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:gravity="right"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textSize="#dimen/font_norm_size"/>
<TextView android:id="#android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#android:id/title"
android:layout_alignRight="#android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/text_aux"
android:maxLines="4"
android:gravity="right"
android:textSize="#dimen/font_aux_norm_size"/>
</RelativeLayout>
</FrameLayout>
I tried a lot to find my answers, even i tried to set padding and margin to "0" but it's not working. How should I fit my own custom preference in holder and use "title" and "summary" in my custom preferences?
I have simple Relative layout with one button.
And Im using this layout multiple times using include in Main Layout.
Its possible to write one method (using ButterKnife or not) for all this buttons using listener(this) and not creating multiple listeners like this ---->
(relativeLayout1.findViewById(R.id.currencyButton)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ForeignExchangeActivity.this, "Euro", Toast.LENGTH_SHORT).show();
}
});
(relativeLayout2.findViewById(R.id.currencyButton)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ForeignExchangeActivity.this, "GBP", Toast.LENGTH_SHORT).show();
}
});
Single item layaout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBackgroundSeekbar">
<TextView
android:id="#+id/currencyTitle"
android:text="EUR - PLN"
android:padding="5dp"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#color/colorButtonHiglight"/>
<TextView
android:id="#+id/currencyDate"
android:layout_below="#id/currencyTitle"
android:text="24-01-2015"
android:textStyle="bold"
android:layout_marginTop="12dp"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/currencyValue"
android:layout_below="#+id/currencyDate"
android:text="4.4567"
android:layout_marginTop="12dp"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:textSize="25sp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorCalculatorActivity"/>
<TextView
android:text="Inna data"
android:textAllCaps="false"
android:layout_marginTop="10dp"
android:id="#+id/currencyButton"
android:textSize="12sp"
android:padding="5dp"
android:gravity="center"
android:layout_below="#id/currencyValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#drawable/button_rounder_corners"
android:layout_alignLeft="#+id/currencyValue"
android:layout_alignRight="#+id/currencyValue"
android:onClick="onClickDataButton"
/>
<View
android:layout_marginTop="10dp"
android:layout_below="#id/currencyButton"
android:layout_width="match_parent"
android:layout_height="1dp"/>
</RelativeLayout>
Example Inlcude
<LinearLayout
android:layout_width="match_parent"
android:weightSum="2"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin">
<include
android:id="#+id/currency1"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
layout="#layout/single_item_foreign_exchange"/>
<View
android:layout_width="10dp"
android:layout_height="match_parent"/>
<include
android:id="#+id/currency2"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
layout="#layout/single_item_foreign_exchange"/>
</LinearLayout>
Binded inlcude layaouts
#Bind(R.id.currency1) RelativeLayout relativeLayout1;
#Bind(R.id.currency2) RelativeLayout relativeLayout2;
SOLVED
Added onClick method to my RelativeLayaout. Then created something like this
public void onClickDataButton(View view){
if (view == buttonEuro){
Toast.makeText(ForeignExchangeActivity.this, "Euro", Toast.LENGTH_SHORT).show();
} else if ( view == buttonGBP){
Toast.makeText(ForeignExchangeActivity.this, "GBP", Toast.LENGTH_SHORT).show();
}
}
And my button looks like
buttonEuro = (TextView) relativeLayout1.findViewById(R.id.currencyButton);
buttonGBP = (TextView) relativeLayout2.findViewById(R.id.currencyButton
);
so the same button id but finded in diffrent layaouts.
EDIT: Example for your case added: Buttons with same ID in different layouts.
1) You could iterate over an Array of Buttons.
2) Or: Create a custom Button-Class which holds anything custom you need (i.e. field for currency etc) and use that in your Layout.
Kind of Pseudocode (not tested):
class CurrencyButton extends android.widget.Button {
string currency;
public void init(Context ctx, String currency) {
this.currency = currency;
this.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ctx, this.currency, Toast.LENGTH_SHORT).show();
}
});
}
public void doSomeOtherFancyCurrencyLogicHere() {
....
}
}
This can be used in your Layout files: (Pseudo)
<your.package.CurrencyButton
id="#+id/currency_button_eur"
LayoutParams etc />
<your.package.CurrencyButton
id="#+id/currency_button_gbp"
LayoutParams etc />
<!-- EDIT: as in your example with layouts in single_item_foreign_exchange -->
<your.package.CurrencyButton
id="#+id/currency_button"
LayoutParams etc />
If you use Butterknife
#InjectView(R.id.currency_button_eur)
your.package.CurrencyButton buttonEUR;
#InjectView(R.id.currency_button_gbp)
your.package.CurrencyButton buttonGBP;
// ... initialize them somewhere
buttonEUR.init(this, "EUR");
buttonGPB.init(this, "GBP");
// EDIT: as in your example with layouts
((your.package.CurrencyButton) relativeLayout1.findViewById(R.id.currencyButton)).init(this, "EUR");
((your.package.CurrencyButton) relativeLayout2.findViewById(R.id.currencyButton)).init(this, "GBP");
Actually you could go even further and extend this class for each currency, but this should do it in the first place.
Ok, I've seen you have SOLVED your question. But since I was already working on this answer, I'll add it here anyway :P
class CurrencyLayout extends FrameLayout {
String currency;
// Constructors that calls init after super(...);
public void init(Context ctx, AtributeSet attrs) {
View includedLayout = LayoutInflater.fromContext(ctx).inflate(R.layout.single_item_foreign_exchange, this, false);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CurrencyLayout,
0, 0);
try {
final String currency = a.getString(R.styleable.CurrencyLayout_currencyName);
} finally {
a.recycle();
}
includedLayout.findViewById(R.id.currencyName).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ctx, this.currency, Toast.LENGTH_SHORT).show();
}
});
}
this.addView(includedLayout);
}
inside res/values/attrs.xml add something like this:
<resources>
<declare-styleable name="CurrencyLayout">
<attr name="currencyName" format="string" />
</declare-styleable>
</resources>
And inside your Activity layout:
<LinearLayout
android:layout_width="match_parent"
android:weightSum="2"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin">
<your_package.CurrencyLayout
android:id="#+id/currency1"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
custom:currencyName="GBP"/>
<View
android:layout_width="10dp"
android:layout_height="match_parent"/>
<your_package.CurrencyLayout
android:id="#+id/currency2"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
custom:currencyName="EUR"/>
</LinearLayout>
I hope this helps you anyway :D
More information on custom views and attributes
i was trying to create custom dialog for my app and i was expecting it to be similar in older API's too. Here's what i've got on Jelly Bean(API 17):
looks awesome :) exactly how i want)
But then i test it on GingerBread (API 10) and here comes this
Please help me. I dont know why my buttons shrinked.
Here's base layout for my dialog
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentPanel"
android:background="#drawable/roundcorner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dip"
android:layout_marginEnd="8dip"
android:orientation="vertical">
<LinearLayout android:id="#+id/topPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout android:id="#+id/title_template"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical|start"
android:minHeight="64dip"
android:layout_marginStart="16dip"
android:layout_marginEnd="16dip">
<ImageView android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="8dip"
android:layout_marginLeft="8dip"
android:src="#null"
android:contentDescription="#string/alert_image_content_description"/>
<com.android.internal.widget.DialogTitle
android:id="#+id/alertTitle"
android:singleLine="true"
android:ellipsize="end"
style="#style/QustomDialogTitleForOlderPlatfoms"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dip" />
</LinearLayout>
<View android:id="#+id/titleDivider"
android:layout_width="match_parent"
android:layout_height="2dip"
android:visibility="visible"
android:background="#FFFFFF" />
</LinearLayout>
<FrameLayout android:id="#+id/customPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/roundcorner">
</FrameLayout>
</LinearLayout>
then in java code i call addView() for the FrameLayout and add View inflated with this layout
<?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="match_parent"
android:background="#drawable/roundcorner"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical" >
<EditText
android:id="#+id/product_name"
style="#style/EditTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:ems="10"
android:hint="Enter your product title" >
<requestFocus />
</EditText>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:orientation="horizontal" >
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<EditText
android:id="#+id/product_amount"
style="#style/EditTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter your product amount" />
</FrameLayout>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_weight="1" >
<Spinner
android:id="#+id/measures_spinner"
style="#style/EditTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/cancel_product_creation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="#drawable/custom_button"
android:padding="4dp"
android:text="Cancel"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/add_new_product_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="#drawable/custom_button"
android:padding="4dp"
android:text="Add"
android:textColor="#FFFFFF" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
This is my code for the Dialog
public class CustomDialog extends Dialog{
/** The custom_body layout */
private View mDialogView;
/** optional dialog title layout */
private TextView mTitle;
/** optional alert dialog image */
private ImageView mIcon;
/** The colored holo divider. You can set its color with the setDividerColor method */
private View mDivider;
private View customView;
public CustomDialog(Context context) {
super(context);
mDialogView = View.inflate(context, R.layout.qustom_dialog_layout, null);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(mDialogView);
getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
mTitle = (TextView) mDialogView.findViewById(R.id.alertTitle);
mIcon = (ImageView) mDialogView.findViewById(R.id.icon);
mDivider = mDialogView.findViewById(R.id.titleDivider);
}
/**
* Use this method to color the divider between the title and content.
* Will not display if no title is set.
*
* #param colorString for passing "#ffffff"
*/
public CustomDialog setDividerColor(String colorString) {
mDivider.setBackgroundColor(Color.parseColor(colorString));
return this;
}
public void setTitle(CharSequence text) {
mTitle.setText(text);
}
public void setTitleColor(String colorString) {
mTitle.setTextColor(Color.parseColor(colorString));
}
public void setIcon(int drawableResId) {
mIcon.setImageResource(drawableResId);
}
public void setIcon(Drawable icon) {
mIcon.setImageDrawable(icon);
}
/**
* This allows you to specify a custom layout for the area below the title divider bar
* in the dialog. As an example you can look at example_ip_address_layout.xml and how
* I added it in TestDialogActivity.java
*
* #param resId of the layout you would like to add
* #param context
*/
public CustomDialog setCustomView(int resId, Context context) {
customView = View.inflate(context, resId, null);
((FrameLayout)mDialogView.findViewById(R.id.customPanel)).addView(customView);
return this;
}
public View getCustomView()
{
return customView;
}
#Override
public void show() {
if (mTitle.getText().equals("")) mDialogView.findViewById(R.id.topPanel).setVisibility(View.GONE);
super.show();
}
}
this is how i use it
dialog = new CustomDialog(getActivity());
dialog.setCustomView(R.layout.add_new_item, getActivity());
dialog.setTitle("Add New Product");
dialog.setTitleColor("#FFFFFF");
dialog.setDividerColor("#FFFFFF");
dialog.setIcon(R.drawable.ic_action_new);
UPD1///
I figured out that the problem is that FrameLayout (#id/customPanel) provides insufficient space for layout_height = "wrap_content" to actually wrap it's content. If i set it's layout height in dp's - everything's all right, but it leaves lots of free space beneath on bigger screens. So how should i force this FrameLayout to show all of it's content?
Change this code:
public CustomDialog setCustomView(int resId, Context context) {
customView = View.inflate(context, resId, null);
((FrameLayout)mDialogView.findViewById(R.id.customPanel)).addView(customView);
return this;
}
To:
public CustomDialog setCustomView(int resId, Context context) {
FrameLayout root = (FrameLayout)mDialogView.findViewById(R.id.customPanel));
LayoutInflater inflater = LayoutInflater.from(context);
customView = inflater.inflate(resId, root, false);
root.addView(customView);
return this;
}
Let me know if that helps.
//EDIT:
Also, have a look at http://developer.android.com/reference/android/app/AlertDialog.html#setView(android.view.View) - maybe that's something better than your current implementation of CustomDialog.
i'm struggling with scrollview.
I want to display content (1) then buttons (2) and finally content (3).
When i'm scrolling, i want the buttons to be fixed at the top of my activity.
I can't post image, so it would be :
1
2
3
I scroll
2 (fixed at top)
3 (this part start to scroll when the 1 disapear at top)
I scroll
2 (fixed at top)
3 (still scrollable).
I m curently using this :
<ScrollView
android:id="#+id/sv_entete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/layout_bar"
android:background="#color/gris_blanc" >
<RelativeLayout
android:id="#+id/layout_conteneur"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
// Some image etc.
</RelativeLayout>
</ScrollView>
<Button
android:id="#+id/btn_presentation_has_to_stay_on_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/sv_entete" />
<Button
android:id="#+id/btn_analyze_has_to_stay_on_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/sv_entete" />
<ScrollView
android:id="#+id/sv_presentation"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/btn_presentation"
android:background="#color/gris_blanc" >
<RelativeLayout
android:id="#+id/layout_presentation"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
// Some image etc
</RelativeLayout>
</ScrollView>
But only the second part scroll (3), the first part (1) is (obviously) not linked with the second scrollview, but i can't figured out by myself.
Any help plz ?
Looks like there's no way to implement it right out of the box. So, You need to create custom components.
Unfortunately, there's not much details in the question, so I'm not able to suggest which way is better for your case.
However, below two variants I can think of:
Have two button panels in the same layout. Initially only one panel should be visible (one inside scroll view). During scrolling, it first panel reaches top, You'll need to make second one visible. And make it invisible, when scroll up (and first one become visible inside ScrollView). It would increase complexity of layout and coe little bit (e.g. You'll need to listen two sets of buttons instead of one). In simple test application I haven't observed any critical issues / UI artifacts using this implementation,
For that you need to create separate layout for buttons panel, e.g. buttons_panel.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/btn_presentation_has_to_stay_on_top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="left button"/>
<Button
android:id="#+id/btn_analyze_has_to_stay_on_top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="right button"/>
</LinearLayout>
Then main activity layout might look like the following (activity_main.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.alexstarc.testapp.ObservableScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/sv_entete">
<RelativeLayout
android:id="#+id/layout_conteneur"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="match_parent"
android:layout_height="300dp"
android:id="#+id/image_1"
android:layout_alignParentTop="true"
android:background="#android:color/holo_blue_dark"
android:gravity="center"
android:textSize="30sp"
android:text="Image 1"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/image_1_1"
android:layout_centerHorizontal="true"
android:layout_below="#id/image_1"
android:src="#drawable/img1"/>
<include
layout="#layout/buttons_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/middle_button_panel"
android:layout_below="#id/image_1_1" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="#+id/image_2"
android:layout_below="#id/middle_button_panel"
android:background="#android:color/holo_green_dark"
android:gravity="center"
android:textSize="30sp"
android:text="Image 2"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="350dp"
android:id="#+id/image_3"
android:layout_below="#id/image_2"
android:src="#drawable/img3"/>
<TextView
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/image_4"
android:layout_below="#id/image_3"
android:background="#android:color/holo_orange_dark"
android:gravity="center"
android:textSize="30sp"
android:text="Image 4 (1)"/>
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="#+id/image_5"
android:layout_below="#id/image_4"
android:background="#android:color/holo_purple"
android:gravity="center"
android:textSize="30sp"
android:text="Image 5"/>
<TextView
android:layout_width="match_parent"
android:layout_height="350dp"
android:id="#+id/image_6"
android:layout_below="#id/image_5"
android:background="#android:color/holo_blue_dark"
android:gravity="center"
android:textSize="30sp"
android:text="Image 6"/>
<TextView
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/image_7"
android:layout_below="#id/image_6"
android:background="#drawable/img1"
android:gravity="center"
android:textSize="30sp"
android:text="Image 7"/>
<TextView
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/image_8"
android:layout_below="#id/image_7"
android:background="#android:color/holo_orange_dark"
android:gravity="center"
android:textSize="30sp"
android:text="Image 8"/>
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="#+id/image_9"
android:layout_below="#id/image_8"
android:background="#android:color/holo_purple"
android:gravity="center"
android:textSize="30sp"
android:text="Image 9"/>
<TextView
android:layout_width="match_parent"
android:layout_height="350dp"
android:id="#+id/image_10"
android:layout_below="#id/image_9"
android:background="#android:color/holo_blue_dark"
android:gravity="center"
android:textSize="30sp"
android:text="Image 10"/>
<TextView
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/image_11"
android:layout_below="#id/image_10"
android:background="#drawable/img1"
android:gravity="center"
android:textSize="30sp"
android:text="Image 11"/>
</RelativeLayout>
</com.alexstarc.testapp.ObservableScrollView>
<include
layout="#layout/buttons_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/top_button_panel"
android:layout_alignParentTop="true"
android:visibility="gone" />
</RelativeLayout>
There's special custom ViewGroup - ObservableScrollView. It's needed, because ScrollView doesn't have any listeners for observing scroll position, but we need to detect then buttons panel inside it become visible. Here's its draft code (please note, I haven't done any optimization or full testing):
public class ObservableScrollView extends ScrollView {
private int mTrackViewId = 0;
private View mTrackView = null;
private int mTrackViewTop = 0;
private int mTrackViewDown = 0;
private OnViewReachTop mTopReachListener = null;
/* Helper interface to notify listener about */
public interface OnViewReachTop {
/**
* Called then View riches top
*/
void onReachTop();
/**
* Called then view leaves top position
*/
void onLeaveTop();
}
public ObservableScrollView(final Context context) {
super(context);
}
public ObservableScrollView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public ObservableScrollView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets view id to be tracked and corresponding callback
*
* #param viewId id of view to be trackked
* #param listener {#link com.alexstarc.testapp.ObservableScrollView.OnViewReachTop} to be called
*/
public void setViewTopTracking(final int viewId, final OnViewReachTop listener) {
mTrackView = findViewById(viewId);
if (mTrackView == null) {
throw new IllegalArgumentException("Passed view id should be from child of this scroll view");
}
mTrackViewId = viewId;
mTopReachListener = listener;
}
#Override
protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
if (mTrackViewDown == 0 && mTrackViewTop == 0) {
mTrackViewDown = mTrackView.getBottom();
mTrackViewTop = mTrackView.getTop();
}
super.onScrollChanged(l, t, oldl, oldt);
if (getScrollY() >= mTrackViewTop) {
mTopReachListener.onReachTop();
} else if (getScrollY() <= mTrackViewDown) {
mTopReachListener.onLeaveTop();
}
}
}
And activity code, which will observe current scroll position and show / hide second buttons panel:
public class MyActivity extends Activity implements ObservableScrollView.OnViewReachTop {
private static final String TAG = "MyActivity";
private View mButtonsPanel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtonsPanel = findViewById(R.id.top_button_panel);
((ObservableScrollView)findViewById(R.id.sv_entete)).setViewTopTracking(R.id.middle_button_panel, this);
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.action_bar, menu);
return true;
}
#Override
public void onReachTop() {
mButtonsPanel.setVisibility(View.VISIBLE);
}
#Override
public void onLeaveTop() {
mButtonsPanel.setVisibility(View.GONE);
}
}
Second way: take ScrollView code, analyze it and make possible to fix some view on the top. This way is more complex, but possible to implement. Please, investigate it (if first one is not applicable to your code / layout) and ask additional questions if face some particular problems with it.
I'd like to easily display custom-style popups across the whole application.
For that in my Utils class I created this static method:
public static Dialog showStyledPopup(Context context, String sHeader, String sMessage,
String sBtn0Text, View.OnClickListener onClick0,
String sBtn1Text, View.OnClickListener onClick1,
String sBtn2Text, View.OnClickListener onClick2)
{
Dialog dialog = new Dialog(context, R.style.dialog_style_no_bg);
dialog.setContentView(R.layout.popup);
dialog.setCancelable(false);
TextView txtHeader = (TextView)dialog.findViewById(R.id.txt_popup_header);
if (null == sHeader)
{
txtHeader.setVisibility(View.GONE);
}
else
{
txtHeader.setText(sHeader);
txtHeader.setTypeface(App.fontHeader);
}
TextView txtMessage = (TextView)dialog.findViewById(R.id.txt_popup_message);
txtMessage.setText(sMessage);
txtMessage.setTypeface(App.fontCommon);
Button btn0 = (Button)dialog.findViewById(R.id.btn_popup_0);
btn0.setVisibility(View.VISIBLE);
btn0.setText(sBtn0Text);
btn0.setTypeface(App.fontCommon);
btn0.setOnClickListener(onClick0);
if (null != onClick1)
{
Button btn1 = (Button)dialog.findViewById(R.id.btn_popup_1);
btn1.setVisibility(View.VISIBLE);
btn1.setText(sBtn1Text);
btn1.setTypeface(App.fontCommon);
btn1.setOnClickListener(onClick1);
}
if (null != onClick2)
{
Button btn2 = (Button)dialog.findViewById(R.id.btn_popup_2);
btn2.setVisibility(View.VISIBLE);
btn2.setText(sBtn2Text);
btn2.setTypeface(App.fontCommon);
btn2.setOnClickListener(onClick2);
}
dialog.show();
return dialog;
}
popup.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="250dp"
android:layout_height="170dp"
android:background="#drawable/dialog_250_170"
android:gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:id="#+id/txt_popup_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:textColor="#android:color/black"
android:textSize="20dp" />
<LinearLayout
android:id="#+id/group_popup_btns"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:orientation="horizontal"
android:baselineAligned="false" >
<Button
android:id="#+id/btn_popup_0"
android:layout_width="60dp"
android:layout_height="40dp"
android:background="#drawable/btn_60_40"
android:textColor="#android:color/black"
android:textSize="20dp" />
<Button
android:id="#+id/btn_popup_1"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_marginLeft="5dp"
android:background="#drawable/btn_60_40"
android:textColor="#android:color/black"
android:textSize="20dp"
android:visibility="gone" />
<Button
android:id="#+id/btn_popup_2"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_marginLeft="5dp"
android:background="#drawable/btn_60_40"
android:textColor="#android:color/black"
android:textSize="20dp"
android:visibility="gone" />
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/group_popup_btns"
android:layout_below="#id/txt_popup_header"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp" >
<ScrollView
android:id="#+id/scroll_popup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/txt_popup_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:textColor="#android:color/black"
android:textSize="18dp" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
</RelativeLayout>
in styles.xml:
<style name="dialog_style_no_bg" parent="#android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
The caller is supposed to pass the View.OnClickListeners.
To be able to close the dialog, the caller must have Dialog dialog field which is then used in the OnClickListener to dismiss the dialog, e.g.:
this.dialog = Utils.showStyledPopup(this, null, getString(R.string.STR_ENABLE_SOUND_AND_MUSIC_Q),
getString(R.string.STR_YES), new View.OnClickListener()
{
#Override
public void onClick(View v)
{
doToggleSound();
doToggleMusic();
dialog.dismiss();
dialog = null;
}
}, getString(R.string.STR_NO), new View.OnClickListener()
{
#Override
public void onClick(View v)
{
dialog.dismiss();
dialog = null;
}
});
The problem is that for some reason in rare cases the dialog field gets reset while the popup is still shown. I can't reproduce this, but got a few crash reports because of this in the field.
Has someone tried to do the same?
The activity has it's orientation fixes to landscape, so onCreate should never get called in-between to reset dialog variable.
I don't like the idea of storing the reference to the dialog, but there is just no way to use a final variable in this case, because it gets a value after it should be passed to the OnClickListener.
My question is similar to Android close custom dialog but the problem there is also not solved, at least as I want it (as 1 method in Utils).
I've seen onCreate() being called on DellStreak device at weird times, so this might be just some device-specific issue (PMP5080BRU)
The solution would be to declare Dialog dialog as class field, declare it at class level.
EDIT
Try this solution too. Have the dialog as class field in the Utils class. Do not return the dialog object from the method, instead use it to initialize the dialog variable. The use a getter method (or try accessing directly though not recommended) of dialog variable. This is kinda dirty solution, but it might work for you too.