How to keep a TextView's content when changing the Activity - android

I'm pretty new to Android Development and I've come across a problem with my TextView. I have an XML file that contains a ScrollView and a TextView:
<ScrollView
android:id="#+id/scroll1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:freezesText="true">
</TextView>
</ScrollView>
And I have included it in two different XML files
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<include
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/story_view"
layout="#layout/story_view" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/add_text">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:text="#string/end_button"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="0dp"
android:onClick="endButtonPressed">
</Button>
<Button android:text="#string/submit_button"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:onClick="textAdded">
</Button>
</LinearLayout>
and
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<include
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="#layout/story_view" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button android:text="#string/save"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="0dp"
android:onClick="saveToDevice">
</Button>
<Button android:text="#string/facebook"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:onClick="saveToFacebook">
</Button>
</LinearLayout>
But when I go from the first XML file to the other (and changing the Activity in the process), the content of the TextView disappears. I have tried freezesText but that doesn't seem to work.
Ordinarily I would just pass the content in an intent but my text is in different colours and I want to maintain that.
I could pass a Bitmap image in an intent but I want to avoid that if possible.
Thanks.

You could use the Activity state to save some values like
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putBoolean("MyBoolean", true);
savedInstanceState.putDouble("myDouble", 1.9);
savedInstanceState.putInt("MyInt", 1);
savedInstanceState.putString("MyString", "Welcome back to Android");
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");
}

That happen because when you come back to the first activity, the onCreate method is called, so your textView is a new textView.
Take a look to Activity Lifecycle, here is explained much better.
You can use sharedPreferences or a Singleton (a design pattern), where the class can be instantiate only one time:
public class MySingleton{
private static MySingleton INSTANCE = null;
private String textViewInformation;
private MySingleton() {
}
public static MySingleton getInstance(Context context) {
synchronized (MySingleton.class) {
if (INSTANCE == null) {
synchronized (MySingleton.class) {
if (INSTANCE == null)
INSTANCE = new MySingleton();
}
}
}
return INSTANCE;
}
public String getTextViewInformation(){
return textViewInformation;
}
public void setTextViewInformation(String textViewInfo){
textViewInformation = textViewInfo;
}
}
and then:
public void onDestroy() {
super.onDestroy();
MySingleton.getInstance(this).setTextViewInformation("textViewText");
}
public void onResume() {
super.onResume();
if(MySingleton.getInstance(this).getTextViewInformation() != null){
yourTextView.setText(MySingleton.getInstance(this).getTextViewInformation());
}else{
yourTextView.setText("new text");
}
Maybe this way it's longer than the shared preferences, but it's very useful.
Excuse my bad english!
I hope this help.

you can use the sharedpreferences for this purpose it allows you to store and retrieve data using key-value pairs. for satisfying your purpose you need to store your activity state in sharedpreferences.
particularly in your case
first you need to store the textview value in shared preferences when you destroy the activity
#Override
public void onDestroy() {
super.onDestroy();
TextView tvText = (TextView) findViewById(R.id.yourelement);
SharedPreferences.Editor prefEditor = getSharedPreferences("Preferences", Context.MODE_PRIVATE).edit();
prefEditor.putBoolean("text", tvText .getText().toString());
prefEditor.commit();
}
Then in onCreate you need to set the textview text from your shared preferences.
TextView tvText = (TextView) findViewById(R.id.yourelement);
SharedPreferences prefs = getSharedPreferences("Preferences", Context.MODE_PRIVATE);
if (prefs.contains("text")){
tvText .setText(prefs.getString("text", ""));
}

Related

Android Studio - Save TextView value for different users

My application has an authentication service made in .net and SSMS(SQL Server)
In one of my activities, I want to store a TextView value (that is incrementing due to the user using the application) so that each user has his own value. For example, user 1 uses the application 1h and closes the application. If user 2 logins in the app, the value should be different. When user 1 logins again, the value should be the last one before he closes the app.
Which method should I use in this case? Should I use SharedPreferences?
EDIT 08/09/2020
UserPoints.java
public class UserPoints extends AppCompatActivity{
private TextView userMoneyTV;
private BroadcastReceiver minuteUpdateReceiver;
private int userMoney = 0;
private Button saveMoney, loadMoney;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_points);
userMoneyTV = (TextView) findViewById(R.id.userMoney);
final String UserMoney = userMoneyTV.getText().toString();
saveMoney = (Button) findViewById(R.id.saveMoney);
saveMoney.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SharedPreferences preferences = getSharedPreferences("MYPREFS",MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("money", UserMoney);
editor.putString("email", String.valueOf(R.id.email));
editor.commit();
}
});
loadMoney = (Button) findViewById(R.id.loadMoney);
loadMoney.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SharedPreferences preferences = getSharedPreferences("MYPREFS",MODE_PRIVATE);
String money = preferences.getString("money",UserMoney);
String email = preferences.getString("email",String.valueOf(R.id.email));
userMoneyTV.setText(money);
}
});
}
public void startMinuteUpdateReceiver(){
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_TIME_TICK);
minuteUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
userMoney++;
userMoneyTV.setText(""+ userMoney);
}
};
registerReceiver(minuteUpdateReceiver,intentFilter);
}
#Override
protected void onResume() {
super.onResume();
startMinuteUpdateReceiver();
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(minuteUpdateReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
activity_user_points.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/rewardLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/rewardInfoLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<ImageView
android:id="#+id/chestReward"
android:layout_width="200dp"
android:layout_height="150dp"
android:layout_marginTop="120dp"
android:src="#drawable/chestreward"
android:layout_alignParentLeft="true">
</ImageView>
<TextView
android:id="#+id/rewardText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginBottom="68dp"
android:layout_toRightOf="#+id/chestReward"
android:text="Earn money every minute you use the app"
android:layout_marginTop="175dp">
</TextView>
</RelativeLayout>
<RelativeLayout
android:id="#+id/moneyInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#+id/rewardInfoLayout">
<TextView
android:id="#+id/userMoneyText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:fontFamily="casual"
android:text="Your Money: "></TextView>
<TextView
android:id="#+id/userMoney"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:layout_toRightOf="#+id/userMoneyText"
android:layout_marginTop="20dp">
</TextView>
<TextView
android:id="#+id/euro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="€"
android:layout_toRightOf="#+id/userMoney"
android:layout_marginTop="20dp"
android:layout_marginLeft="5dp">
</TextView>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/moneyInfo">
<Button
android:id="#+id/saveMoney"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save Money"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"
android:onClick="startVideoAd">
</Button>
<Button
android:id="#+id/loadMoney"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Load Money"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"
android:layout_below="#+id/saveMoney">
</Button>
</RelativeLayout>
</RelativeLayout>
EDIT 9/9/2020
My problem was solved with EDIT 8/9/2020
Now my question is, how can i make the value increasing when i'm in another activity? AsyncTask?
Yes, you can use the SharedPreferences but if the user uninstalls the application user will lose its data and the value you've stored in SharedPreferences.
And if you want to save data even after uninstalling the app you can use any lightweight database i.e. Realm,Room,SQLite,Firebase and store your local database in users sd card. Else use Google backup service or store it in another place like on your server.

SharedPreferences Click Checkbox And Hiding Button

I have two activities, ActivityA and ActivityB. ActivityA has a Checkbox, ActivityB has a Button. When I click the Checkbox in ActivityA, I want the Button in ActivityB to be invisible. I want it to be visible when I lift the tick. And most importantly I want to save it with SharedPreferences. So I want to exit the program and re-enter the last process I do. Could someone please help me? Thanks in advance.
activity_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
tools:context=".MainActivity"
android:orientation="vertical">
<CheckBox
android:id="#+id/chk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FF5722"
android:textStyle="bold"
android:textSize="18sp"
android:layout_margin="25dp"
android:text="Show Button"/>
<android.support.v7.widget.AppCompatButton
android:id="#+id/btn"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:background="#000"
android:textSize="14sp"
android:textColor="#fff"
android:textAllCaps="false"
android:text="Next Screen"/>
</LinearLayout>
In Activity A :you can acheive using sharedpreference.
Step 1 : put below code in your A activity and yes btn is used for checking next screen button is hidden or not
SharedPreferences sharedPreferences = getSharedPreferences("ButtonPrefs", MODE_PRIVATE);
#SuppressLint("CommitPrefEdits") final SharedPreferences.Editor editor=sharedPreferences.edit();
chk=findViewById(R.id.chk);
btn=findViewById(R.id.btn);
chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
{
editor.putBoolean("isShow",false);
editor.apply();
}
else
{
editor.putBoolean("isShow",true);
editor.apply();
}
}
});
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
}
});
activity_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main2Activity"
android:orientation="vertical">
<android.support.v7.widget.AppCompatButton
android:layout_margin="50dp"
android:id="#+id/btnshoworhide"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:background="#000"
android:visibility="gone"
android:textSize="14sp"
android:textColor="#fff"
android:textAllCaps="false"
android:text="show me or not"/>
</LinearLayout>
Step 1 : put below code in your B activity
boolean showornot;
btnshoworhide=findViewById(R.id.btnshoworhide);
SharedPreferences sharedPreferences = getSharedPreferences("ButtonPrefs", MODE_PRIVATE);
showornot=sharedPreferences.getBoolean("isShow",false);
if(!showornot)
{
btnshoworhide.setVisibility(View.GONE);
}
else
{
btnshoworhide.setVisibility(View.VISIBLE);
}
Its Easy && Nice
I run this code successfully ;)
You can pass data from activity A to B by Intent,
Intent intent = new Intent(ctx, B.class);
intent.putExtra("checkbox_result", "true");
startActivity(intent);
And get data in B Activity and save this string in shared preference:
String check= getIntent().getStringExtra("checkbox_result");
You can use a common sharedPreference which is accessible allover your application. put data on it from activity A and read it from activity B.
get instance of it from both activity like this.
SharedPreference sp = PreferenceManager.getDefaultSharedPreference(context);
saved data on it,
SharedPreference.Editor editor = sp.getEditor();
editor.putBoolean(MY_BOL, checkboxValue).apply();
read saved value from same preference you used to save to, get an instance of it the same way you did while saving as shown above,
get value, do this in onCreate() method of activity N.
boolean bol = sharedPreference. getBoolean(MY_BOL, false);
button.setVisibility(bol);

DialogPreference in Full Screen Width

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!

save the URLs entered by the user in Android using Shared Preferences

So I am creating an android application which opens the url entered by the user. Now each time an url is entered by the user, it needs to be save using the "save" button and the save list is seen using the "list" button.
This is my Interface:
This is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.application.mota_app.MainActivity"
tools:showIn="#layout/activity_main">
<TextView
android:text="#string/enter_the_url_below"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/enter_URL"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="26dp"
android:textSize="19sp"
android:textColor="#android:color/holo_green_dark" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/txtbox_website"
android:layout_marginTop="18dp"
android:width="300dp"
android:inputType="textUri"
android:layout_below="#+id/enter_URL"
android:layout_centerHorizontal="true" />
<Button
android:text="#string/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btn_save"
android:textColor="#color/colorAccent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:text="#string/visit"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:id="#+id/btn_visit"
android:textColor="#android:color/holo_blue_dark"
android:onClick="open"
android:layout_marginBottom="50dp"
android:layout_alignBottom="#+id/btn_save"
android:layout_centerHorizontal="true" />
<Button
android:text="#string/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btn_list"
android:textColor="?android:attr/colorPressedHighlight"
android:layout_below="#+id/btn_save"
android:layout_alignLeft="#+id/btn_save"
android:layout_alignStart="#+id/btn_save" />
</RelativeLayout>
So I am stuck in the save and list. I am using shared preferences, but I am not able to save and list the URLS. This is the code I wrote:
public class MainActivity extends AppCompatActivity {
public static final String MY_EMP_PREFS = "MyPrefs";
private EditText url;
private Button save;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
url = (EditText)findViewById(R.id.txtbox_website);
save = (Button)findViewById(R.id.btn_save);
}
public void open(View view){
if (url.getText().toString().matches("")) {
Toast.makeText(getApplicationContext(), "Enter a website to open!", Toast.LENGTH_SHORT).show();
return;
}
if (!url.getText().toString().startsWith("http://") && !url.getText().toString().startsWith("https://"))
{
url.setText("http://" + url.getText().toString());
}
if (!Patterns.WEB_URL.matcher(url.getText().toString()).matches())
{
Toast.makeText(getApplicationContext(), "Invalid URL!", Toast.LENGTH_SHORT).show();
url.setError("Enter a valid URL");
url.setText("");
url.setSelection(0);
return;
}
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url.getText().toString()));
startActivity(browserIntent);
}
public void save(View view) {
SharedPreferences pref = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
// We need an editor object to make changes
SharedPreferences.Editor edit = pref.edit();
// Set/Store data
edit.putString("save", url.getText().toString());
// Commit the changes
edit.commit();
Toast.makeText(getApplicationContext(), "URL Saved", Toast.LENGTH_SHORT).show();
}
Where am I going wrong? What should I do?
Thanks
You have to add the method reference in your Widget:
<Button
android:text="#string/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btn_save"
android:onClick="save" //HERE
android:textColor="#color/colorAccent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
Also, when you use a SharedPreferences, you are putting a String value using the key "save". So when you click on save button, you are overriding the old value and put a new value in the place.
To solve this issue, I think the best solution is use a Framework to persist the data and list it after.
edit.putString("save", url.getText().toString()); //here you are overriding the vlaue

Textviews in a Fragment layout don't change when calling SetText()

My application (min level 13) is an Activity that uses tabs in the action bar to manage a couple fragments, very similar to this.
Now, the activity starts a service which does continuous computation and returns values which I would like to display in the Fragments. The Activity - Service communication is implemented through broadcast receivers and the Activity shuffles the data off to the appropriate Fragment.
Everything seems setup correctly and the data makes it to the Fragment update method but when I try to display the new values in textviews, the new values are never displayed.
The code to change the textviews:
TextView tv = (TextView) getView().findViewById(R.id.fieldNavGpsTime);
Double doub = input.getDoubleExtra("com.some.thing.GPS_TIME", -1.0);
tv.setText(doub.toString());
The code to call the Fragments update methods from the broadcast receiver in the Activity:
NavigationGuiFragment navfrag = (NavigationGuiFragment) getFragmentManager().findFragmentByTag("navigation");
if (navfrag != null && navfrag.isResumed())
navfrag.UpdateNavUI(intent);
I've noticed that isVisible() doesn't seem to ever return true, but I'm not sure what it means or how to change it.
Additionally, I can't seem to add an imageview to a Fragment programmatically. Here's the code (which resides in onActivityCreated()):
this.compass = new BasicCompass(getActivity());
LinearLayout ll = (LinearLayout) getView().findViewById(R.id.nav_hrztl_lnly);
ll.addView(this.compass);
The BasicCompass constructor takes a Context, admittedly I'm not completely sure what I'm passing in is correct.
The code for this was more or less taken from a working Activity and dropped into a Fragment to allow for tabs. I'm open to suggestion in regards to changing the structure of the code.
Thanks for any help.
EDIT
The xml layout of the Fragment:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/nav_hrztl_lnly"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:focusable="true"
android:focusableInTouchMode="true"
android:baselineAligned="false" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="600dp"
android:layout_height="fill_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true" >
<EditText
android:id="#+id/labelNavGpsTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/gps_time" />
<EditText
android:id="#+id/fieldNavGpsTime"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_3_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavLatitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/latitude" />
<EditText
android:id="#+id/fieldNavLatitude"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavLongitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/longitude" />
<EditText
android:id="#+id/fieldNavLongitude"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavAltitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/altitude" />
<EditText
android:id="#+id/fieldNavAltitude"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_3_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavRoll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/roll" />
<EditText
android:id="#+id/fieldNavRoll"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavPitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/pitch" />
<EditText
android:id="#+id/fieldNavPitch"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/labelNavAzimuth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/azimuth_heading" />
<EditText
android:id="#+id/fieldNavAzimuth"
style="#style/field_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/zero_6_digits"
android:inputType="numberDecimal" />
<LinearLayout
android:id="#+id/nav_rdbtn_lnly"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RadioButton
android:id="#+id/rdbtnNavGpsAvailability"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/gps_avail" />
<RadioButton
android:id="#+id/rdbtnNavZuptStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/zupt_stat" />
</LinearLayout>
</LinearLayout>
And the Fragment that uses it:
public class NavigationGuiFragment extends Fragment
{
private RadioButton gpsRdBtn;
private RadioButton zuptRdBtn;
private BasicCompass compass;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View fragview = inflater.inflate(R.layout.navigation_fragment, container, false);
// sets up the rose image that serves as a compass in the GUI
this.compass = new BasicCompass(getActivity());
LinearLayout ll = (LinearLayout) fragview.findViewById(R.id.nav_hrztl_lnly);
ll.addView(this.compass);
return fragview;
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
getActivity().setContentView(R.layout.navigation_fragment);
//Initialize the radio buttons
gpsRdBtn = (RadioButton) getView().findViewById(R.id.rdbtnNavGpsAvailability);
gpsRdBtn.setChecked(false);
zuptRdBtn = (RadioButton) getView().findViewById(R.id.rdbtnNavZuptStatus);
zuptRdBtn.setChecked(false);
}
#Override
public void onResume()
{
super.onResume();
if (!IsMyServiceRunning())
{
gpsRdBtn.setChecked(false);
zuptRdBtn.setChecked(false);
}
}
public void UpdateNavUI(Intent input)
{
TextView tv = (TextView) getView().findViewById(R.id.fieldNavGpsTime);
Double doub = input.getDoubleExtra("com.some.thing.GPS_TIME", -1.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavLatitude);
doub = input.getDoubleExtra("com.some.thing.LATITUDE", 100000.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavLongitude);
doub = input.getDoubleExtra("com.some.thing.LONGITUDE", 100000.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavAltitude);
doub = input.getDoubleExtra("com.some.thing.ALTITUDE", -1.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavRoll);
doub = input.getDoubleExtra("com.some.androidndk.ROLL", 361.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavPitch);
doub = input.getDoubleExtra("com.some.thing.PITCH", 361.0);
tv.setText(doub.toString());
tv = (TextView) getView().findViewById(R.id.fieldNavAzimuth);
doub = input.getDoubleExtra("com.some.thing.AZIMUTH", 361.0);
tv.setText(doub.toString());
this.compass.SetDirection(doub.floatValue());
boolean bool = input.getBooleanExtra("com.some.thing.ZUPT_STATUS", false);
zuptRdBtn.setChecked(bool);
UpdateGpsIndicator(input);
}
public void UpdateGpsIndicator(Intent input)
{
boolean bool = input.getBooleanExtra("com.some.thing.GPS_ON", false);
gpsRdBtn.setChecked(bool);
}
private boolean IsMyServiceRunning()
{
ActivityManager manager = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
{
if ("com.some.thing.Service".equals(service.service.getClassName()))
return true;
}
return false;
}
}
this line:
getActivity().setContentView(R.layout.navigation_fragment);
should be called in Activity.onCreate() and make sure it is just called once. In your code it will be called every time Fragment moves to active state. And the TextView and RaidoButton stuff will be reset to state define in the layout xml.
Checkout Fragment lifecycle here.
UPDATE:
Some view widget's state will be kept by Activity, e.g TextView. Try move your setXXX() method to onResume(). I have experience that setXXX() is not working in onActivityCreated() but works well in onResume().

Categories

Resources