I have some buttons and I have some text set ot them and I need that text to be visible when activity starts. After that I set some text to all my buttons from sqlite database, but I don't want that text to be visible until user clicks of a button.
The simplest solution would be to use button.setText(c.getString(int)); and set that text from db when a button is clicked, but my c cursor is not in activity scope so I can't use it in my onClick method of my buttons. I tried to place everything inside of my nextQuestion() method in activity scope, but that gives me errors.
So I was thinking I should hide all text set from db until a button is pressed, that unhide it. How to do that? Or if first idea is possible somehow it's even better.
Here's my game class:
public class Game extends Activity implements View.OnClickListener{
Button b1, b2, b3, b4, b5, b6, b7, b8, b9, b10;
MediaPlayer buttonClicks;
public boolean music;
LinkedList<Long> mAnsweredQuestions = new LinkedList<Long>();
private String generateWhereClause(){
StringBuilder result = new StringBuilder();
for (Long l : mAnsweredQuestions){
result.append(" AND _ID <> " + l);
}
return result.toString();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
addListenerOnButton();
nextQuestion();
}
private void addListenerOnButton() {
buttonClicks = MediaPlayer.create(this, R.raw.button);
b1 = (Button) findViewById(R.id.button1);
b2 = (Button) findViewById(R.id.button2);
b3 = (Button) findViewById(R.id.button3);
b4 = (Button) findViewById(R.id.button4);
b5 = (Button) findViewById(R.id.button5);
b6 = (Button) findViewById(R.id.button6);
b7 = (Button) findViewById(R.id.button7);
b8 = (Button) findViewById(R.id.button8);
b9 = (Button) findViewById(R.id.button9);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
b4.setOnClickListener(this);
b5.setOnClickListener(this);
b6.setOnClickListener(this);
b7.setOnClickListener(this);
b8.setOnClickListener(this);
b9.setOnClickListener(this);
}
private void nextQuestion() {
TestAdapter mDbHelper = new TestAdapter(this);
mDbHelper.createDatabase();
try{
mDbHelper.open();
Cursor c = mDbHelper.getTestData(generateWhereClause());
mAnsweredQuestions.add(c.getLong(0));
b1.setText(c.getString(2));
b2.setText(c.getString(3));
b3.setText(c.getString(4));
b4.setText(c.getString(5));
b5.setText(c.getString(6));
b6.setText(c.getString(7));
b7.setText(c.getString(8));
b8.setText(c.getString(9));
b9.setText(c.getString(10));
}
finally{
mDbHelper.close();
}
}
public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
if(music == true){
buttonClicks.start();
}
b1.setText(c.getString(2));// this is a good option, but can't use cursor
b2.setEnabled(true);
break;
case R.id.button2:
if(music == true){
buttonClicks.start();
}
b3.setEnabled(true);
break;
case R.id.button3:
if(music == true){
buttonClicks.start();
}
break;
case R.id.button4:
if(music == true){
buttonClicks.start();
}
}
}
}
There is no builtin method to hide only the text on a button, but you could simply store the values from the database in a bunch of variables and not set those against the buttons until they're pressed.
That means you should change:
b1.setText(c.getString(2));
b2.setText(c.getString(3));
...
b9.setText(c.getString(10));
To something like:
String mButtonText1, mButtonText2, ... mButtonText9; // <-- class members
mButtonText1 = c.getString(2);
mButtonText2 = c.getString(3);
...
mButtonText9 = c.getString(10);
(alternatively, you could put these values in an array)
And then in onClick():
b1.setText(mButtonText1);
To 'hide' the text on the button, simply call setText() with "" or null.
You may be able to achieve the same effect by setting the button's text color to 'transparent', but I haven't tried that.
How about passing the String-s to some intermediate storage in some variables and then, at appropriate time, setting the Buttons' texts from those strings?
You're trying to find a solution for a symptom of a larger, underlying problem. If you're having difficulties sharing data between activities, you certainly shouldn't be heading in this direction.
That being said, to answer your specific question, you could set textColor to android.R.color.transparent.
I think the best way is:
Setting text null or empty and in your java implementation, you set text.
Like this:
teste.xml:
<Button android:id="#+button/testebutton" android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
Teste.java:
Button testeButton = (Button) findViewById(R.button.testebutton);
testeButton.setText("NEW TITLE");
How about making the cursor an instance variable (of the class) instead of method-local variable? And maybe using http://en.wikipedia.org/wiki/Lazy_initialization ...
Related
I know that was already asked but it is outdated:
I have 2 buttons that represent 2 choices and if one is selected the background color gets changed to yellow. But if i want to change the choice i need to somehow reset the button:
I already try to set it back but some old design comes out. Can you provide me the id of the modern button style? And show me how to implement it?
int myChoice;
if (view == findViewById(R.id.choice1)){
myChoice = 1;
choice1.setBackgroundColor(getResources().getColor(R.color.highlightButton));
choice2.setBackgroundResource(android.R.drawable.btn_default);
}
else if (view == findViewById(R.id.choice2)){
myChoice = 2;
choice2.setBackgroundColor(getResources().getColor(R.color.highlightButton));
choice1.setBackgroundResource(android.R.drawable.btn_default);
}
}
Use Tags with getBackground(). This will assure you are always setting back to original.
Add following in beginning of function
if (v.getTag() == null)
v.setTag(v.getBackground());
Then instead of setBackgroundResource, use
v.setBackground(v.getTag());
Starting from here, you can store the default color of the button into a Drawable and grab the selection color (Yellow in your case) into anther Drawable, then toggle background colors of buttons with these Drawable variables
please check below demo
public class MainActivity extends AppCompatActivity {
private Drawable mDefaultButtonColor;
private Drawable mSelectedButtonColor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn1 = findViewById(R.id.btn1);
final Button btn2 = findViewById(R.id.btn2);
mDefaultButtonColor = (btn1.getBackground());
mSelectedButtonColor = ContextCompat.getDrawable(this, R.color.buttonSelected);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggleButton(btn1, true);
toggleButton(btn2, false);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggleButton(btn1, false);
toggleButton(btn2, true);
}
});
}
private void toggleButton(Button button, boolean isSelected) {
button.setBackground(isSelected ? mSelectedButtonColor : mDefaultButtonColor);
}
}
My code works with an if statement that counts until 10 moves are made and then checks who the winner is in getWinner() but, that is an issue when somebody wins before all 10 moves are made.
I originally had just the getWinner(); method with no if statement assuming this would check for a winner every time a button is clicked. This did not give me any errors but it simply did not work properly.
What else can I try? Why does just adding the getWinner(); without the if statement not work?
public class MainActivity extends AppCompatActivity {
public int counter = 1;
private Button button1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
//This repeats for all buttons, I left it all out for the sake of making the post shorter.
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (button1.getText().toString().equals("")) {
if (counter % 2 == 0) {
button1.setText("O");
} else {
button1.setText("X");
}
counter++;
}
if (counter == 10) {
getWinner();
}
}
});
//add the other buttons here...
public void getWinner() {
String b1, b2, b3, b4, b5, b6, b7, b8, b9;
b1 = button1.getText().toString();
// code here
}
Looks like none of the buttons aside from button1 matters:
b1 = button1.getText().toString();
b2 = button1.getText().toString();
b3 = button1.getText().toString();
b4 = button1.getText().toString();
b5 = button1.getText().toString();
b6 = button1.getText().toString();
b7 = button1.getText().toString();
b8 = button1.getText().toString();
b9 = button1.getText().toString();
Based on your comment: "I originally had just the GetWinner(); method with no if statement assuming this would check for a winner every time a button is clicked. This did not give me any errors but it simply did not work properly."
Assuming the code was not being executed as you expected when you attempted the above. I would suggest making a callback to GetWinner() every time the button is clicked.
With all the Strings getting their value from the first button did it work if you clicked the first button?
I am making a calculator and below is my code. I was wondering is there any way to shorten the code, I have 18 buttons and I have to write 50 lines of code just to take reference from XML and add click listener to it
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
String SelectedOpertator;
int num1, num2, result;
EditText input;
Button b1, b2, b3, b4, b5, b6 ,b7, b8, b9, b0, bdot;
Button bc, bs, bd, bp, bmi, bm, be;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
input = (EditText) findViewById(R.id.input);
b1 = (Button) findViewById(R.id.b1);
b2 = (Button) findViewById(R.id.b2);
b3 = (Button) findViewById(R.id.b3);
b4 = (Button) findViewById(R.id.b4);
b5 = (Button) findViewById(R.id.b5);
b6 = (Button) findViewById(R.id.b6);
b7 = (Button) findViewById(R.id.b7);
b8 = (Button) findViewById(R.id.b8);
b9 = (Button) findViewById(R.id.b9);
b0 = (Button) findViewById(R.id.b0);
bdot = (Button) findViewById(R.id.bdot);
bc = (Button) findViewById(R.id.bc);
bs = (Button) findViewById(R.id.bs);
bd = (Button) findViewById(R.id.bd);
bp = (Button) findViewById(R.id.bp);
bmi = (Button) findViewById(R.id.bmi);
bm = (Button) findViewById(R.id.bm);
be = (Button) findViewById(R.id.be);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
b4.setOnClickListener(this);
b5.setOnClickListener(this);
b6.setOnClickListener(this);
b7.setOnClickListener(this);
b8.setOnClickListener(this);
b9.setOnClickListener(this);
b0.setOnClickListener(this);
bdot.setOnClickListener(this);
bc.setOnClickListener(this);
bs.setOnClickListener(this);
bd.setOnClickListener(this);
bp.setOnClickListener(this);
bmi.setOnClickListener(this);
bm.setOnClickListener(this);
be.setOnClickListener(this);
}
Is there any other way to write this code in shorter way?
If you add a method to do the findViewById and setOnClickListener, you can reduce the lines for each button from two to one:
private Button findAndSetClickListener(int id) {
Button button = (Button) findViewById(id);
button.setOnClickListener(this);
return button;
}
Then:
b1 = findAndSetClickListener(R.id.b1);
// etc.
int ids[] = new int[] {R.id.b1, R.id.b2, R.id.b3, R.id.b4, R.id.b5, R.id.b6, R.id.b7, R.id.b8, R.id.b9, R.id.b0}
for(int i = 0; i < ids.length, i += 1){
findViewById(ids[i]).setOnClickListener(this);
}
There's no need for storing reference to each button as class members. In the onClick listener we can determine which button was clicked.
public onClick(View v){
int number = Arrays.asList(ids).indexOf(v.getId()) + 1;
// Button 'number' was clicked
}
try this type code.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
String SelectedOpertator;
int num1, num2, result;
EditText input;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
input = (EditText) findViewById(R.id.input);
((Button) findViewById(R.id.b1)).setOnClickListener(this);
((Button) findViewById(R.id.b2)).setOnClickListener(this);
((Button) findViewById(R.id.b3)).setOnClickListener(this);
((Button) findViewById(R.id.b4)).setOnClickListener(this);
((Button) findViewById(R.id.b5)).setOnClickListener(this);
((Button) findViewById(R.id.b6)).setOnClickListener(this);
((Button) findViewById(R.id.b7)).setOnClickListener(this);
((Button) findViewById(R.id.b8)).setOnClickListener(this);
((Button) findViewById(R.id.b9)).setOnClickListener(this);
((Button) findViewById(R.id.b0)).setOnClickListener(this);
((Button) findViewById(R.id.bdot)).setOnClickListener(this);
((Button) findViewById(R.id.bc)).setOnClickListener(this);
((Button) findViewById(R.id.bs)).setOnClickListener(this);
((Button) findViewById(R.id.bp)).setOnClickListener(this);
((Button) findViewById(R.id.bmi)).setOnClickListener(this);
((Button) findViewById(R.id.bm)).setOnClickListener(this);
((Button) findViewById(R.id.be)).setOnClickListener(this);
}
You could write an array where you store the views.
So that you can do something like
for (View v : array.getView()) {
v.setOnClickListener(this)
}
I think the actual findViewById would be a little more complicated to simplify
You could shorten it at about 50% (and make it a lot more readable) with a private method:
private Button getButtonWithListener(int id) {
Button btn = (Button) findViewById(id);
btn.setOnClickListener(this);
return btn;
}
and call this at every button: (saves you the setOnClickListener)
b1 = getButtonWithListener(R.id.b1);
b2 = getButtonWithListener(R.id.b2);
b3 = getButtonWithListener(R.id.b3);
b4 = getButtonWithListener(R.id.b4);
b5 = getButtonWithListener(R.id.b5);
b6 = getButtonWithListener(R.id.b6);
b7 = getButtonWithListener(R.id.b7);
b8 = getButtonWithListener(R.id.b8);
b9 = getButtonWithListener(R.id.b9);
b0 = getButtonWithListener(R.id.b0);
bdot = getButtonWithListener(R.id.bdot);
bc = getButtonWithListener(R.id.bc);
bs = getButtonWithListener(R.id.bs);
bd = getButtonWithListener(R.id.bd);
bp = getButtonWithListener(R.id.bp);
bmi = getButtonWithListener(R.id.bmi);
bm = getButtonWithListener(R.id.bm);
be = getButtonWithListener(R.id.be);
This way you're not losing the reference to the button. If you need those references to the buttons it won't become much shorter. If you don't need them, then there are some excellent possibilities in the other answers here!
If you need to shorten the button code, Use View's in OnClick() with help of switch statement.
In your XML Layout:
Create the number of buttons that you want with different button id. But use same method name for all button's onClick attribute. Eg: android:onClick="submitBTN" used for all buttons.
In your MainActivity:
Implement that method name to perform different operations using switch statement
public void submitBTN(View view) {
switch (view.getId()) {
case R.id.btnClick1: // Code of button 1 Click
break;
case R.id.btnClick2: // Code of button 2 Click
break;
case R.id.btnClick3: // Code of button 3 Click
break;
case R.id.btnClickn: // Code of Button n Click
}
}
Try using butter knife library. You can use syntax like:
#Onclick({R.id.b1, R.id.b2...})
public void handleClick(Button btn){
// handle click event here
}
I'm looking to call a few buttons but seem to be getting a NULL when trying to findbyviewid. When I activate this activity, it crashes.
//CREATE INSTANCE OF GLOBAL - QUESTIONS/ANSWERS
Global global = Global.getInstance();
//CURRENT QUESTION
static int QQ = 0;
//CORRECT ANSWER COUNT
static int correctAnswers = 0;
//CREATE VARIABLE FOR TEXTVIEW/QUESTION
TextView textQuestion = (TextView) findViewById(R.id.textQuestion);
//CREATE VARIABLES FOR BUTTONS/ANSWERS
Button buttonOne = (Button) findViewById(R.id.answerOne);
Button buttonTwo = (Button) findViewById(R.id.answerTwo);
Button buttonThree = (Button) findViewById(R.id.answerThree);
Button buttonFour = (Button) findViewById(R.id.answerFour);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice_questions);
setButtons();
buttonOne.setOnClickListener(this);
buttonTwo.setOnClickListener(this);
buttonThree.setOnClickListener(this);
buttonFour.setOnClickListener(this);
}
public void setButtons()
{
//SET QUESTION STRING TO TEXTVIEW
textQuestion.setText(global.getQ(QQ));
//SET ANSWER STRINGS TO BUTTONS' TEXT
buttonOne.setText(global.getA(QQ, 0));
buttonTwo.setText(global.getA(QQ, 1));
buttonThree.setText(global.getA(QQ, 2));
buttonFour.setText(global.getA(QQ, 3));
}
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.answerOne:
checkAnswer(0, buttonOne);
break;
case R.id.answerTwo:
checkAnswer(1, buttonTwo);
break;
case R.id.answerThree:
checkAnswer(2, buttonThree);
break;
case R.id.answerFour:
checkAnswer(3, buttonFour);
break;
default:
break;
}
}
public void checkAnswer(int a, Button b){
//IF AN INCORRECT ANSWER WAS CHOSEN, MAKE THE BACKGROUND RED
if(!global.getS(QQ, a))
{
b.setBackgroundColor(Color.RED);
}
else
{
//INCREMENT THE CORRECT ANSWER COUNTER
correctAnswers++;
}
//SET BACKGROUND OF CORRECT BUTTON TO GREEN
if(global.getS(QQ, 0))
{
buttonOne.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 1))
{
buttonTwo.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 2))
{
buttonThree.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 3))
{
buttonFour.setBackgroundColor(Color.GREEN);
}
else
{
//IF NO ANSWER IS CORRECT, SET ALL TO BLUE
buttonOne.setBackgroundColor(Color.BLUE);
buttonTwo.setBackgroundColor(Color.BLUE);
buttonThree.setBackgroundColor(Color.BLUE);
buttonFour.setBackgroundColor(Color.BLUE);
}
//MOVE TO NEXT QUESTION
}
I have 4 buttons in the XML file and want to be able to set the text to them, as well as run a listener for the set of buttons (answers to a question). When one of the buttons is clicked, it should determine if it's the correct answer by pulling the status (true/false) and highlighting it red if it's incorrect. It then highlights the correct answer green.
At least, some of this is in theory and I'm trying to test it out, but I can't start the activity without crashing.
I'm not 100% sure but I think you can't do the findViewById at the instance constructions. You need to those inside onCreate() (after you called setContentView)
Just how i said in comment, you should initialize it in OnCreate method, cause you set view layout for activity here. And before you do it, all findViewById returns null.
So, here your code:
Button buttonOne;
Button buttonTwo;
Button buttonThree;
Button buttonFour;
TextView textQuestion;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice_questions);
buttonOne = (Button) findViewById(R.id.answerOne);
buttonTwo = (Button) findViewById(R.id.answerTwo);
buttonThree = (Button) findViewById(R.id.answerThree);
buttonFour = (Button) findViewById(R.id.answerFour);
textQuestion = (TextView) findViewById(R.id.textQuestion);
[...]
}
Right now I have an Adapter class, which extends PagerAdapter. Inside I have my InstantiateItem() method.
Here I have instantiate several buttons on the view:
#Override
public Object instantiateItem(ViewGroup parent, final int position) {
final int delPosition = position;
//Get the inflater
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//inflate the root layout
View view = inflater.inflate(R.layout.collection, null);
//Grab instance of image
ImageView imageView = (ImageView) view.findViewById(R.id.region);
//Sets a drawable as the content of this ImageView.
imageView.setImageResource(regionImages.get(position));
//scores toggle buttons
zero = (ToggleButton) view.findViewById(R.id.number_zero);
one = (ToggleButton) view.findViewById(R.id.number_one);
two = (ToggleButton) view.findViewById(R.id.number_two);
three = (ToggleButton) view.findViewById(R.id.number_three);
four = (ToggleButton) view.findViewById(R.id.number_four);
five = (ToggleButton) view.findViewById(R.id.number_five);
six = (ToggleButton) view.findViewById(R.id.number_six);
seven = (ToggleButton) view.findViewById(R.id.number_seven);
eight = (ToggleButton) view.findViewById(R.id.number_eight);
nine = (ToggleButton) view.findViewById(R.id.number_nine);
ten = (ToggleButton) view.findViewById(R.id.number_ten);
one.setOnClickListener(createClickListener(1));
two.setOnClickListener(createClickListener(2));
three.setOnClickListener(createClickListener(3));
four.setOnClickListener(createClickListener(4));
five.setOnClickListener(createClickListener(5));
six.setOnClickListener(createClickListener(6));
seven.setOnClickListener(createClickListener(7));
eight.setOnClickListener(createClickListener(8));
nine.setOnClickListener(createClickListener(9));
ten.setOnClickListener(createClickListener(10));
//Back Arrow Button
final ImageView back_button = (ImageView) view.findViewById(R.id.back_nav_arrow);
back_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//it doesn't matter if you're already in the first item
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
}
});
//forward button
final ImageView forward_button = (ImageView) view.findViewById(R.id.forward_nav_arrow);
forward_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//it doesn't matter if you're already in the last item
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
}
});
parent.addView(view, 0);
return view;
}
Here's the onClick action for the buttosn:
//onClickListener method that returns an interface
private View.OnClickListener createClickListener(final int value) {
return new View.OnClickListener() {
#Override
public void onClick(View view) {
buttonValue = value;
ToggleButton clickedButton = (ToggleButton) view;
RadioGroup radioGroup= (RadioGroup) clickedButton.getParent();
for (int i = 0; i < radioGroup.getChildCount(); ++i) {
View nextChild = radioGroup.getChildAt(i);
if (!(nextChild instanceof ToggleButton)) {
continue;
}
if (nextChild.getId() != clickedButton.getId() || !clickedButton.isChecked()) {
ToggleButton tb2 = (ToggleButton) nextChild;
tb2.setChecked(false);
}
}
}
};
}
I want to be able to save the state of the button press (right now it's like a radiobutton and when the user clicks on it, the button state is pressed down until they move to another button) and the buttonValue between the views in the viewpager.
Ultimately, I want a view at the end of my viewpager where I can list all the scores for each view as well as have the user go back to the other views and still have their button state pressed so that they can confirm it while swiping between views.
I am facing two problems right now:
1) Only the last buttonValue is saved and not all the buttonValues for all the views. How can I achieve saving all the scores in all the views and not just the last score in the last view?
2) Going from one view to another and back, the button state is still pressed. However, if I go to a third view from the last point, the button state pressed is no longer true. How can I fix this?
I think it is time to use fragment, although you can achieve what you want without it but using fragment gives a lot of benefits like saving your value when your activity is destroyed (rotation) or using the life cycle callback methods or reusing it to your future projects. anyway:
1) Only the last buttonValue is saved and not all the buttonValues for
all the views. How can I achieve saving all the scores in all the
views and not just the last score in the last view?
save the state of your button in anyway you like for example in sharedpreference, database or a list of custom object as a member of your activity or adapter something like below:
class MyToggleButton{
boolean mState; // false = unpressed, true = pressed
}
and use List<MyToggleButton> to store them.
2) Going from one view to another and back, the button state is still
pressed. However, if I go to a third view from the last point, the
button state pressed is no longer true. How can I fix this?
you can use List<MyToggleButton> at instantiateItem to determine which button must have which state so you can set it correctly. when user change the state of any button you must update MyToggleButton state so that when ever you are going to look at List<MyToggleButton> find the correct one.