In my MainActiviy class I want to display image views of smiley faces based on the number of clicks that occur on the buttons jokes, poems and funnystories combined. However my switch statement does not seem to working as no images appear. Also if any of those image views become visible, then they should remain visible even after the user closing the app and reopening it.
I also notice a click count increasing by one when the user opens the app which is not correct. It should increase based on the buttons mentioned previously being clicked.
public class MainActivity extends AppCompatActivity {
SharedPreferencesManager prefManager = SharedPreferencesManager.getInstance(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button jokesButton = findViewById(R.id.button_jokes);
Button poemsButton = findViewById(R.id.button_poems);
Button funnyStoriesButton = findViewById(R.id.button_funny_stories);
ImageView yellowSmileyFace = findViewById(R.id.yellow_happy);
ImageView greenSmileyFace = findViewById(R.id.green_happy);
ImageView redSmileyFace = findViewById(R.id.red_happy);
jokesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prefManager.increaseClickCount();
openContentPage("jokes");
}
});
poemsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prefManager.increaseClickCount();
openContentPage("poems");
}
});
funnyStoriesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prefManager.increaseClickCount();
openContentPage("funnystories");
}
});
TextView clickCountText = findViewById(R.id.click_count);
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
switch (prefManager.increaseClickCount()){
case 4 :
yellowSmileyFace.setVisibility(View.VISIBLE);
break;
case 8 :
greenSmileyFace.setVisibility(View.VISIBLE);
break;
case 12 :
redSmileyFace.setVisibility(View.VISIBLE);
break;
default :
yellowSmileyFace.setVisibility(View.INVISIBLE);
greenSmileyFace.setVisibility(View.INVISIBLE);
redsmileyFace.setVisibility(View.INVISIBLE);
}
}
private void openContentPage(String v) {
Intent intentContentPage = new Intent(MainActivity.this, Content.class);
intentContentPage.putExtra("keyPage", v);
startActivity(intentContentPage);
}
}
below is the Shared preferences class
public class SharedPreferencesManager {
private static final String APP_PREFS = "AppPrefsFile";
private static final String NUMBER_OF_CLICKS = "numberOfClicks";
private SharedPreferences sharedPrefs;
private static SharedPreferencesManager instance;
private SharedPreferencesManager(Context context) {
sharedPrefs = context.getApplicationContext().getSharedPreferences(APP_PREFS, MODE_PRIVATE);
}
public static synchronized SharedPreferencesManager getInstance(Context context){
if(instance == null)
instance = new SharedPreferencesManager(context);
return instance;
}
public int increaseClickCount() {
int clickCount = sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
clickCount++;
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putInt(NUMBER_OF_CLICKS, clickCount);
editor.apply();
return clickCount;
}
}
You need to add a getter for your clicks
public int getClicks(){
return sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
}
Whenever you want to get your clicks currently you are calling increaseClickCount() which causes your clicks to increment before returning them. That is why it gains clicks every time you open the stage and why your switch isn't working correctly
so add the above getter to your SharedPrefrenceManager and change these two lines
switch (prefManager.increaseClickCount()){
to
switch (prefManager.getClicks()){
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
to
clickCountText.setText(Integer.toString(prefManager.getClicks()));
Tell me if that fixes your problem
The reason for counts' increase is you use increaseClickCount() to receive click count.You have to create another method to receive current clickCount. Your switch statement works only when they equal to 4,8 or 12. Maybe you should use if instead.
I also notice a click count increasing by one when the user opens the app which is not correct
It looks to me like this line of code, in MainActivity.onCreate() method will pass a text String of count 1 to clickCountText.
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
Also, every time you call SharedPreferencesManager.increaseClickCount, you are assigning a value to clickCount, and whatever was there gets overwritten.
int clickCount = sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
What is that value?
System.out.println is your friend.
I use this pattern
System.out.println("MyClass, MyMethod, MyVariable:" + myVariable);
I always include the class and method because it can be annoying trying to figure out where println are coming from if you leave several in for debugging purposes and want to get rid of them later.
Related
I have 6 options that the user can select from and a button that takes them to the next page when clicked. I have two pages like this. After one choice from each page is selected, I would like to display certain text depending on the radio buttons clicked previously, in another activity. How can I do this in java in android studio?
If you are controlling the FragmentManager you can just pass the options as an argument to the next Fragment's constructor otherwise, you can save everything in a static variable (as long as no Views are in there, so don't store the radio buttons there) and access that variable from outside.
Like this:
public class MyFragment {
public static boolean isRadioButtonXPressed = false; //change to true if it's pressed by default
public void onCreate(...) {
radioButtonX.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
isRadioButtonXPressed = checked;
}
});
}
}
//from the other fragment
public class MyFragment2 {
public void onCreateView(...) {
if (MyFragment.isRadioButtonXPressed) {
//it's been pressed
} else {
//it's not been pressed
}
}
}
There are many different ways.
As you are using activity, you can use Intent to pass data. Here is a sample:
Intent page = new Intent(FirstActivity.this, SecondActivity.class);
page.putExtra("key", "This is my text");
startActivity(page);
For getting the value on Second Activity onCreate() method:
String value = getIntent().getStringExtra("key");
At first my main problem was at how to call a method from the same class, even tough I think I found a way to do this, it's not working as I expected, and I would like to know what would be the best approach to my case.
This is the code I'm working on:
public class EscolhaAtendimento extends AppCompatActivity {
private ViewPager mSlideViewPager;
private LinearLayout mDotLayout;
String TAG = "TasksSample";
private TextView[] mDots;
private SliderAdapter sliderAdapter;
Dialog myDialog;
#Override
public void onCreate (Bundle SavedInstanceState){
super.onCreate(SavedInstanceState);
setContentView(R.layout.escolha_atendimento);
mSlideViewPager = findViewById(R.id.slideViewPager);
mDotLayout = findViewById(R.id.dotsLayout);
sliderAdapter = new SliderAdapter(this);
mSlideViewPager.setAdapter(sliderAdapter);
addDotsIndicator(0);
mSlideViewPager.addOnPageChangeListener(viewListener);
myDialog = new Dialog(this);
}
public void addDotsIndicator(int position){
mDots = new TextView[8];
mDotLayout.removeAllViews();
for (int i= 0; i < mDots.length; i++){
mDots[i] = new TextView(this);
mDots[i].setText(Html.fromHtml("•"));
mDots[i].setTextSize(35);
mDots[i].setTextColor(getResources().getColor(R.color.colorTransparentWhite));
mDotLayout.addView(mDots[i]);
}
if (mDots.length > 0){
mDots[position].setTextColor(getResources().getColor(R.color.colorWhite));
}
}
ViewPager.OnPageChangeListener viewListener = new ViewPager.OnPageChangeListener(){
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected (int i) {
switch (i) {
case 0: {
myDialog.show();
}
addDotsIndicator(i);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
};
public void ShowPopup(View v) {
TextView txtclose;
//Button btnFollow;
myDialog.setContentView(R.layout.pop_upfinal);
txtclose = myDialog.findViewById(R.id.txtclose);
txtclose.setText("X");
//btnFollow = (Button) myDialog.findViewById(R.id.btnfollow);
txtclose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myDialog.dismiss();
}
});
myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
myDialog.show();
}
}
This class is an activity that on user swipe, the text and image from the buttons will change, even though their IDs will stay the same. (That's controlled by another class, it's working well).
Now, I wanted the image button on the activity do something different depending on which page is selected, and that's why there is a initial switch on the onPageSelected method, inside the Page change listener. The image button in the layout has the android:onClick="ShowPopup" tag, and I guess that also complicates things for me, if I wanted it to do something different in that same activity? Also, calling it that way on the switch, every time I change pages, and go back to the first one the popup window will open, since my call is explicit there. (As I said, even tough I found a way to somehow call my method, or at least it's result, it's not working as I expected).
Edit
I tried then changing it like this, so that the button wouldn't rely on the android:onClick="ShowPopup" Tag, and also wouldn't need to call a void method directly on the switch:
Added
public ImageButton popupchoice;
And also this to onCreate method:
popupchoice = this.findViewById(R.id.imgslide1);
Inside the switch I called it like this to get the button ID:
popupchoice.setOnClickListener(image1);
And set the View.OnClickListener like this:
View.OnClickListener image1 = new View.OnClickListener() {
public void onClick(View v) {
TextView txtclose;
//Button btnFollow;
myDialog.setContentView(R.layout.pop_upfinal);
txtclose = myDialog.findViewById(R.id.txtclose);
txtclose.setText("X");
//btnFollow = (Button) myDialog.findViewById(R.id.btnfollow);
txtclose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myDialog.dismiss();
}
});
myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
myDialog.show();
}
};
But that returns me:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at .EscolhaAtendimento$1.onPageSelected(EscolhaAtendimento.java:81) Line 81 is the one inside the switch with the popupchoice.setOnClickListener(image1).
This error happens on page change, when coming back to the first Page, and also the button click won't work anymore.
I think you can use
EscolhaAtendimento.this.ShowPopup from inside your switch.
My aim is to allow users select from a list of available themes in my app and make it permanent till they wish to change it again, but i have only been able to achieve that partially. For now, when a user changes the app theme it does change and remains even after the app is minimized and resumed but when a user exits the app and reopens it, the theme goes back to default which is not what i want.
My question now is, how can i make the selected theme permanent even when a user exits the app? I have tried to search for some solutions online but haven't found any that helped me
ThemeActivity.java
public class ThemeActivity extends AppCompatActivity {
public Button blackbtn,bluebtn,pinkbtn,redbtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
themeUtils.onActivityCreateSetTheme(this);
setContentView(R.layout.activity_theme);
blackbtn = findViewById(R.id.blackbutton);
bluebtn = findViewById(R.id.bluebutton);
pinkbtn = findViewById(R.id.pinkbutton);
redbtn = findViewById(R.id.redbutton);
blackbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.BLACK);
}
});
bluebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.BLUE);
}
});
pinkbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.PINK);
}
});
redbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.RED);
}
});
}
themeUtils.java
public class themeUtils {
private static int cTheme;
public final static int BLACK = 0;
public final static int BLUE = 1;
public final static int PINK = 2;
public final static int RED = 3;
public static void changeToTheme(Activity activity, int theme) {
cTheme = theme;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
public static void onActivityCreateSetTheme(Activity activity) {
switch (cTheme)
{
default:
case BLACK:
activity.setTheme(R.style.BlackTheme);
break;
case PINK:
activity.setTheme(R.style.pink);
break;
case RED:
activity.setTheme(R.style.red);
break;
case BLUE:
activity.setTheme(R.style.BlueTheme);
break;
}
}
The simplest solution for this would be to save your selected theme in SharedPreferences. Whenever the app launches, you read the saved value from your SharedPreferences and load the appropriate theme.
To write your selected theme
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.selected_app_theme), YOUR_APP_THEME);
editor.commit();
To read the saved value
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.integer.default_app_theme);
int appTheme = sharedPref.getInt(getString(R.string.selected_app_theme), defaultValue);
EDIT Based on comment
Whenever you change your app theme, you need to save it to SharedPreferences. So, whenever the changeToTheme method is called, after changing the theme, just save it to SharedPrefs. You could create a method which would save the theme like so
void saveThemeToSharedPrefs(int appTheme) {
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("MY_APP_THEME, appTheme);
editor.commit();
}
Next time, when your app starts, you will load this value and use it to change the theme like so
int getAppTheme() {
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = 0 //For Black theme. Change it to whatever you want as default
int appTheme = sharedPref.getInt("MY_APP_THEME", defaultValue);
}
//Change the theme in your starting activity
ThemeUtils.changeToTheme(activity, getAppTheme())
I have a fragment with a button that sets a background theme for the whole app. I have set up an interface so the fragment can tell the main activity to set the background or remove it depending on what button the user clicks.
The problem is that every time the app is opened the background isn't saved and needs to be toggled again. I have seen that this can be solved with SharedPreferences but implementing it here is confusing me
In my fragment This presents two buttons that send the values 1 or 2 to the main activity to toggle the background
enable = (Button) rootView.findViewById(R.id.enable);
enable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.themechanged(2);
enable.setVisibility(View.GONE);
disable.setVisibility(View.VISIBLE);
}
});
disable = (Button) rootView.findViewById(R.id.disable);
disable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.themechanged(1);
disable.setVisibility(View.GONE);
enable.setVisibility(View.VISIBLE);
}
});
In my Main Activity This takes the value from the listener and toggles the background depending on what the value is
#Override
public void themechanged(int value) {
if(value==2) {
if (isDarkTheme) {
appbackground.setVisibility(View.GONE);
shade.setVisibility(View.GONE);
} else {
appbackground.setVisibility(View.VISIBLE);
shade.setVisibility(View.VISIBLE);
}
}else if(value!=2||value==1){
appbackground.setVisibility(View.GONE);
shade.setVisibility(View.GONE);
}
}
Use SharedPrefence to store the value for theme like-:
Global Variable
SharedPreferences pref;
SharedPreferences.Editor editor;
In OnCreateView()
pref = getActivity().getSharedPreferences("Theme", Context.MODE_PRIVATE);
editor = pref.edit();
Now, store preferences on Button click
enable = (Button) rootView.findViewById(R.id.enable);
enable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editor.putInt("yourTheme", 2);
editor.commit();
listener.themechanged(2);
enable.setVisibility(View.GONE);
disable.setVisibility(View.VISIBLE);
}
});
disable = (Button) rootView.findViewById(R.id.disable);
disable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editor.putInt("yourTheme", 1);
editor.commit();
listener.themechanged(1);
disable.setVisibility(View.GONE);
enable.setVisibility(View.VISIBLE);
}
});
and then, In OnCreate() of MainActivity you can check like
SharedPreferences pref = getSharedPreferences("Theme", MODE_PRIVATE);
value= pref.getInt("yourTheme", 1);//1 is default value
if(value==2) {
if (isDarkTheme) {
appbackground.setVisibility(View.GONE);
shade.setVisibility(View.GONE);
} else {
appbackground.setVisibility(View.VISIBLE);
shade.setVisibility(View.VISIBLE);
}
}else if(value==1){
appbackground.setVisibility(View.GONE);
shade.setVisibility(View.GONE);
}
Done, it may be helpful
In the onClick() you should do 2 things:
Sent the value to the listener (you're already doing this)
Save this value to the preferences (already posted how to do that here)
Then, in the onCreate() of your MainActivity you should check for that preference and do the same you are doing on themechanged(int)
Actually, you could use only one onClickListener(), this way:
// Not need to cast to `Button`, since all views can have an onClickListener
rootView.findViewById(R.id.enable).setOnClickListener(clickListener)
rootView.findViewById(R.id.enable).setOnClickListener(clickListener)
// Put this as a member of your Fragment class.
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.getId() == R.id.enable) {
// Save your preference here
// ...
listener.themechanged(2);
enable.setVisibility(View.GONE);
disable.setVisibility(View.VISIBLE);
}
if (v.getId() == R.id.R.id.disable) {
// Save your preference here
// ...
listener.themechanged(2);
disable.setVisibility(View.GONE);
enable.setVisibility(View.VISIBLE);
}
}
}
Let me share this more complex example which can cover this and future needs: https://gist.github.com/walterpalladino/4f5509cbc8fc3ecf1497f05e37675111
The PersistenceManager class is generic, all your app data should be included in the Settings class.
I hope it helps.
I'm having troubles with a custom Dialog in Eclipse.
in the first place, I created a Class that extend Dialog.
public class ModificarGrupoBCDialog extends Dialog {
private static final int CANCELAR = 999;
private static final int MODIFICAR = 1;
...
somewhere I create the buttons...
protected void createButtonsForButtonBar(Composite parent) {
this.createButton(parent, MODIFICAR, "Modificar", true);
this.getButton(MODIFICAR).setEnabled(puedeAltaGrupoBC());
this.bt_ok = this.getButton(MODIFICAR);
this.createButton(parent, CANCELAR, "Cancelar", false);
Display display = window.getShell().getDisplay();
Image image = new Image(display, ModificarGrupoBCDialog.class.getResourceAsStream("/icons/modificar.png"));
this.getButton(MODIFICAR).setImage(image);
image = new Image(display, ModificarGrupoBCDialog.class.getResourceAsStream("/icons/cancelar.png"));
this.getButton(CANCELAR).setImage(image);
}
and when the user clicks...
protected void buttonPressed(int buttonId) {
switch (buttonId) {
case MODIFICAR:
// Some Code, for Change Button
break;
case CANCELAR:
setReturnCode(CANCELAR);
close();
break;
}
Finally, this is how I open and get the returnCode, in the caller object.
...
ModificarGrupoBCDialog modificarGrupoBC = new ModificarGrupoBCDialog(window.getShell(), window, gr_bc);
if (modificarGrupoBC.getReturnCode() == Window.OK) {
//... Some code on OK
} else {
//another code when cancel pressed.
}
;
as you can see, after trying a while, I have to write setReturnCode() in CANCELAR switch block, is that OK ?
I spect that Dialog class automatically asign the correct return code.
May be someone could point me to a good sample.
I'm reading Vogela's blog, and may be the solution is to override okPressed() method ?
Best Regards.
The standard dialog sets the return code in two places:
protected void okPressed() {
setReturnCode(OK);
close();
}
protected void cancelPressed() {
setReturnCode(CANCEL);
close();
}
so your code doing:
setReturnCode(xxxx);
close();
should be fine as long as the button id you are using does not match the Cancel or OK button ids.
You could also use the approach used by MessageDialog which simply does this:
protected void buttonPressed(int buttonId) {
setReturnCode(buttonId);
close();
}