I would really like to set the layout depending on which combination of two checkboxes are selected. Since there are four possible states, I have four layouts to display items underneath the checkboxes, if selected. I have made this work using four classes, but there must be a more efficient way to do this.
Basically, I would like to have drop-down EditTexts for user input displayed under the checkboxes only if they are selected. If the setContentView statements are replaced with the commented ones, I can cycle through any combination of checkboxes, but as the code is, only one layout change is able to be made and I don't understand why. Please help with any suggestions.
**I realize the CompoundButton object is unused here.
public class First extends Activity implements OnCheckedChangeListener{
CheckBox emailBox,smsBox;
#Override public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_1);
emailBox=(CheckBox)findViewById(R.id.checkBox_1);
smsBox=(CheckBox)findViewById(R.id.checkBox_2);
emailBox.setOnCheckedChangeListener(this);
smsBox.setOnCheckedChangeListener(this);
}
public void onCheckedChanged(CompoundButton compound,boolean isChecked){
if(!emailBox.isChecked()&&!smsBox.isChecked()){
setContentView(R.layout.activity_1);
// Toast.makeText(First.this,"None Checked",Toast.LENGTH_SHORT).show();
}
if(emailBox.isChecked()&&!smsBox.isChecked()){
setContentView(R.layout.activity_2);
// Toast.makeText(First.this,"Email Checked",Toast.LENGTH_SHORT).show();
}
if(smsBox.isChecked()&&!emailBox.isChecked()){
setContentView(R.layout.activity_3);
// Toast.makeText(First.this,"Sms Checked",Toast.LENGTH_SHORT).show();
}
if(emailBox.isChecked()&&smsBox.isChecked()){
setContentView(R.layout.activity_4);
// Toast.makeText(First.this,"Both Checked",Toast.LENGTH_SHORT).show();
}
}
}
More efficient way will be use fragments instead of changing layouts :)ORGroup Controls in layouts and set thier visiblity to View.GONE then set visiblility for appropriate group to View.Visible
To display a drop-down info box (like a text view) you can place e.g a lable which is empty(or rather you hide it) under these two check boxes and check for changes in checkboxes and then change the lable I mentioned earlier in runtime using java part of the code to display what u want. I hope I've got your point and this will help you.
I was able to solve this issue very simply by wrapping the relevant portions of the layout in a vertical LinearLayout and toggling between visibility='gone' and visibility='visible' as indicated in the code below; so I eventually thought I should come back here to share (if anyone has a simpler, more efficient method, perhaps let me know?)
public class MainActivity extends Activity implements OnCheckedChangeListener{
CheckBox emailBox,smsBox;
LinearLayout portion_1,portion_2,portion_3;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
portion_1=(LinearLayout)findViewById(R.id.hider_1);
portion_2=(LinearLayout)findViewById(R.id.hider_2);
portion_3=(LinearLayout)findViewById(R.id.hider_3);
emailBox=(CheckBox)findViewById(R.id.checkBox_1);
smsBox=(CheckBox)findViewById(R.id.checkBox_2);
emailBox.setOnCheckedChangeListener(this);
smsBox.setOnCheckedChangeListener(this);
}
public void onCheckedChanged(CompoundButton compound,boolean isChecked){
if(!emailBox.isChecked()&&!smsBox.isChecked()){
portion_1.setVisibility(View.GONE);
portion_2.setVisibility(View.GONE);
portion_3.setVisibility(View.GONE);
emailBox.setChecked(false);
smsBox.setChecked(false);
}
if(emailBox.isChecked()&&!smsBox.isChecked()){
portion_1.setVisibility(View.VISIBLE);
portion_2.setVisibility(View.GONE);
portion_3.setVisibility(View.VISIBLE);
emailBox.setChecked(true);
smsBox.setChecked(false);
}
if(smsBox.isChecked()&&!emailBox.isChecked()){
portion_1.setVisibility(View.GONE);
portion_2.setVisibility(View.VISIBLE);
portion_3.setVisibility(View.VISIBLE);
emailBox.setChecked(false);
smsBox.setChecked(true);
}
if(emailBox.isChecked()&&smsBox.isChecked()){
portion_1.setVisibility(View.VISIBLE);
portion_2.setVisibility(View.VISIBLE);
portion_3.setVisibility(View.VISIBLE);
emailBox.setChecked(true);
smsBox.setChecked(true);
}
}
}
Related
My problem is to understand how RecyclerView works.. I have RecyclerView with a little bit complicated item in every row, but the main thing is that Item has a child ImageView and LinearLayout. I want to press ImageView and set Visibility of LinearLayout to GONE or VISIBLE and rotate my ImageView. I tried to do this in my onBindViewHolder:
holder.mIVExpandBtn.setOnClickListener(new OnClickListener() {
boolean isOpen = false;
#Override
public void onClick(View v) {
if (isOpen) {
CounterListAdapter.this.notifyItemChanged(position);
holder.mLLDetails.setVisibility(GONE);
holder.mDivider.setVisibility(VISIBLE);
holder.setArrowUp(false);
isOpen = false;
counterItem.setDetailsOpened(false);
} else {
holder.mLLDetails.setVisibility(VISIBLE);
holder.mDivider.setVisibility(GONE);
holder.setArrowUp(true);
isOpen = true;
counterItem.setDetailsOpened(true);
}
}
});
And I have some problems here.
I have a boolean variable inside OnClickListener, I know its wrong, so it changes only one time when I expand my LinearLayout. If I make this boolean global variable, if I expand one row of RecyclerView isOpen = true for any other item and it doesn't expand itself when I click on ImageView.. Where should I place this boolean?
And the second question - how can I save the state of my RecyclerView rows on screen rotation? For example I expanded one of my rows, LinearLayout.setVisibility(VISIBLE), change screen orientation and its closed.
For your first problem, you should put your boolean variable where you also define your views, i.e., inside your ViewHolder, ir order that onClick you call the boolean this way
if(holder.isOpen)
In this way you keep the reference of each boolean to each row.
For your second problem, the solution is pretty simple. In your manifest, in the activity where you have your RecyclerView, define the following:
android:configChanges="keyboardHidden|orientation|screenSize"
This prevents your activity from being recreated on configuration change in case you rotate the screen, so the activity will keep it's state and your RecyclerView will therefor not be recreated along with your adapter.
Notice that this means that, if your activity is not recreated, onPause, onStop, etc, will not run. This is only for screen rotation, your activity will still run the method onConfigurationChanged() which is where you should define any changes you need in case the screen rotates.
You better put the OnClickListener in the Holder class, something like this:
private class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
#Override
public void onClick(View view) {
....
}
About how to save state I think all things that define the rows should be saved in the array you pass to the adapter contructor, you can add fields in the array item object that save VISIBILITY state of the row views.
On screen rotation then two options:
1 - as #Ricardo said avoiding Activity recreation
2 - onSaveInstanceState / onRestoreInstanceStates save/restore the array that define the rows .. my prefered method for that is to use JSON and put it in a String that can be saved/restored in the Bundle.
I have added checkboxes dynamically in my onCreate() method. When one or more of them are checked I want two buttons to be displayed. I am new to working with Android, but from what I can tell it won't work to do this check (see if checkboxes are checked) in the same method as the checkboxes are added, i.e. onCreate(), because they can't be found, i.e. haven't been created yet? If this is the case, in what method should I do the check? I want to add the checkboxes at startup of the activity and to check if the boxes are checked all the time.
The checkboxes are added in displayEntries(db).
Here is my onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DatabaseHandler db = new DatabaseHandler(this);
displayEntries(db);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, AddActivity.class); //FromActivity.this
startActivity(i);
}
});
checkChecked();
}
checkChecked():
public void checkChecked() {
//Check whether items have been checked
TableLayout tl = (TableLayout) findViewById(R.id.entry_table);
for (int i = 0; i < tl.getChildCount(); i++) {
View child = tl.getChildAt(i);
if (child instanceof CheckBox) {
CheckBox checkBoxChild = (CheckBox) child;
Log.d("Checkbox", "Checkbox is found");
if (checkBoxChild.isChecked()) {
Log.d("Checkbox", "working!");
Button button1 = (Button) findViewById(R.id.button_edit);
button1.setVisibility(View.INVISIBLE);
Button button2 = (Button) findViewById(R.id.button_delete);
button2.setVisibility(View.INVISIBLE);
}
}
}
}
(At the moment I am trying to make the buttons invisible as you could see above, since I didn't want to "hardcode" in the layout file that they should be invisible to start with - thought that might make it impossible to change? But that's a later question...)
EDIT: I realised my mistake was thinking that the checkboxes where children of my TableLayout. They were in fact children of the rows in the TableLayout. Now that I managed to locate the actual checkbox, I can make the buttons disappear by setting them as invisible when creating them and visible onClick. The remaining problem is that the buttons of course stay visible even if all buttons are unchecked again. Any ideas on how to toggle the buttons on and off depending on if any of the checkboxes are checked or not?
Did not understand your question at first. Please ignore my first answer.
If you want to listen on a check box you might want to try
myCheckBox.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
//do something
}
});
Anything you do in onCreate() will be re-created with each activity cycle.
Therefore you might want to store the state of the check box, and change that state when someone clicks on it.
EDIT after #Ingrid comment:
Looks like there are two problems that need to be solved. One is saving the state and restoring it in on activity/fragment cycle, the other is setting the buttons visible based on condition of N checkboxes.
Assuming you are working with a database object you have an option to use dynamically created check boxes to manipulate the data in your Database Object. The checkboxes represent Boolean values in your DB object or list of objects. Since the checkboxes are dynamic and represent things in your DB, it does not make much sense to store their state in two places. If you do that, things will get out of sync and you will have a nasty bug. Rather rely on the DB object instead. Thus, update your DB object when you click on a checkbox. In onResume() retrieve that DB object (from bundle or DB depending on your architecture) and set your checkboxes / button state based on the state of the DB object.
You can use onPause() to persist your db object. or persist it on click of the check box so your don't have to wary about losing the state in-between. use onResume to setup your UI component base on the current state of the db object. Last but not least, when you update your db object check if you need to show/hide the buttons. (That is if there are on fixed number of buttons but N number of check boxes.
Hope this helps.
//Use shared preference to save.
SharedPreferences preferedName=getSharedPreferences("SavedName", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferedName.edit();
editor.putboolean("SavedName",value);
editor.apply();
editor.commit();
//and to retrive.
SharedPreferences preferedName=getSharedPreferences("SavedName", Activity.MODE_PRIVATE);
boolean chkNull =preferedName.getString("SavedName",false);
and use the boolean as the value of the checkbox.
you can see check CompoundButton because CheckBox inherit from CompoundButton
https://developer.android.com/reference/android/widget/CompoundButton.html#setOnCheckedChangeListener(android.widget.CompoundButton.OnCheckedChangeListener)
checkBoxChild.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
});
I'm using a PreferenceFragment and want the version of my app to appear below the List that holds all the settings. I know for a normal ListView I could just do addFooterView(theTextView), but the PreferenceFragment doesn't provide access to doing this (no access to the ListView that is populated from preferences xml). Anyone have a slick way of doing this?
George's answer (Option 1) was on the right track, but I found it better to take it one step further than simply adding a preference. I created a custom preference by using the layout in the accepted answer here, and then was able to totally customize what I wanted to show by centering text, and even making the preference only appear under certain circumstances (for example, if the user has the most recent version, don't show the preference, etc.).
I used the Android docs on Settings to create a class that extends Preference to do the dynamic work needed.
You can add an empty preference item in the end of xml, then give it an custom layout.
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- other preferences -->
<Preference app:layout="#layout/place_holder" />
</PreferenceScreen>
In your PreferencesFragment, just new a custom PreferenceCategory, then add it to PreferenceScreen. you can do your things in the onCreateView part of the custom PreferenceCategory.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
initPrefs();
PreferenceCategory preferenceCategory = new PreferenceCategory(getActivity()) {
#Override
protected View onCreateView(ViewGroup parent) {
super.onCreateView(parent);
View view =
getActivity().getLayoutInflater().inflate(R.layout.layout_infos, null);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "thanks", Toast.LENGTH_SHORT).show();
}
});
return view;
}
};
getPreferenceScreen().addPreference(preferenceCategory);
}
public class Calculator extends Activity {
String[] measurement;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calculator);
Try calling invalidate after calling setText.
Firstly, i'd suggest using an integer to hold position of selected spinner item and comparing that; rather than .equals("GRAM") - strings can sometimes get a bit tricky.
Secondly, comment out the toast in else statement; make sure that the if loop is actually being executed.
Lastly, try
value_eighth_amt.setText(eighth_amt_int + " "); for all the textviews.
I have several LinearLayouts contained inside their respective ScrollView which in turn are contained by a ViewFlipper. The odd stuff is that in some of the Layouts once they have the focus, it starts automatically in a place other than the top.
So what can be causing this ? In order to force them to start at the top, is there something like the tabindex property in html ?
Thanks
if you have problem called focus is gone automatically on other place instead of top position's field then you have to write this code simply at onStart() method of activity life cycle with respective field id in my case first field
is referenced by firstfield_et this is the variable of Activity.java file and it is also already referenced by etfirstfield from .xml file
the code is simply as below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText firstfield_et= (EditText) findViewById(R.id.etfirstfield);
}
#Override
protected void onStart() {
super.onStart();
if(TextUtils.isEmpty(firstfield_et.getText().toString())){
firstfield_et.requestFocus();
}
}