Having problems updating the visibility of a button within a popup - java

I'm trying to get it so that when the user clicks popbtnnext within the popup, the program checks if the rest of the array flaggedwordsused is null. If not, the button is set to be visible and the program moves on. If it is null, the program updates the button to be invisible.
popbutnext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
f++;
for (int g= f+1; g<flagwordsused.length; g++) {
if (flagwordsused[g] != null) {
popbutnext.setVisibility(0);
break;
}
else{
poptv1.setText(""+f);
popbutnext.setVisibility(1);
}
}
}
});
flagwordsused is an array of 20 elements, f in my test case starts at 0 with the string "very" occupying element zero and all other values are null. I have a textView updating with values of f so that I know the program is getting to the else statement. That value is updating just fine but the visibility of the button never changes. Any help you could give me would be appreciated. The popuplayout was created in java, not xml if that makes any difference.

You should use the constants in View to set visibility instead. Makes the code easier to read too:
To make popbutnext invisible:
popbutnext.setVisibility(View.INVISIBLE);
To make popbutnext invisible and not take any space when building the layout:
popbutnext.setVisibility(View.GONE);
To make popbutnext visible:
popbutnext.setVisibility(View.VISIBLE);
The reason that it does not work for you is because the values are wrong. Invisible is 4, gone is 8, visible is 0. However, I still recommend to use the constants in the View class - you never know, they might change in coming Android versions. Take a look at this link, and the visibility parameter.

Related

getText() always return empty string from dynamically created Chip component?

I'm trying to dynamically create some choice chip components based on an ArrayList of String from some computation and following are the code to create the chips and adding them to a ChipGroup created in layout XML file.
if (mChipGroup.getChildCount() == 0 ){
int i = 0;
for (Classifier.Recognition res: results){
Chip resultChip = new Chip(getDialog().getContext());
ChipDrawable chipDrawable =
ChipDrawable.createFromAttributes(
getActivity(),
null,
0,
R.style.Widget_MaterialComponents_Chip_Choice);
resultChip.setId(i++);
resultChip.setChipDrawable(chipDrawable);
resultChip.setText(res.getTitle());
mChipGroup.addView(resultChip);
}
}
The Chips displayed correctly with the text but when I tried to call getText() on the chips, it always return empty String but not the text contained by the chips. I tested this by setting the OnCheckedChangeListener on the ChipGroup and making a Toast with the text (though it didn;'t work). When I tried to display only the checkedId it works.
mChipGroup.setOnCheckedChangeListener(new ChipGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(ChipGroup group, int checkedId) {
Chip chip = group.findViewById(checkedId);
if(chip != null){
Toast.makeText(getContext(), chip.getText().toString(),Toast.LENGTH_SHORT).show();
}
}
});
My current workaround is to have a variable holding the array results and use ArrayList.get(selectedChipId.getTitle()). but don't think it should be that way though
I also found that it is able to get text from Chips added in layout file but not run-time added Chips. Tried with both 1.1.0/alpha06 and 1.1.0/alpha07 release but am having no luck. Would like to have some advice if possible. Thank you very much.
So, it seems like a bug as per answered in here and here. Current workaround is to use ((ChipDrawable) chip.getChipDrawable()).getText() instead.

While loop causing activity screen to show nothing?

Whenever I make a while loop in an app for android, it causes my screen to show only the basic background & action bar. It was very frustrating when I found this in my app, and I've spent the past couple hours attempting to find a workaround. I've made a very basic program trying to narrow down the cause and found it to be the while loop, which leaves me with a blank screen.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Assign Variables
EditText editText_HEX = (EditText)findViewById(R.id.EditText_HEX);
String stringHEX = editText_HEX.getText().toString();
Boolean isHex = stringHEX.matches("^#([A-Fa-f0-9]{6})$");
// I have (true) in right now, but if I change that to a more specific boolean I still
// can't see the page of my app.
while (true){
// Here I'm trying to get the loop to pause until the user enters 7 characters
// into the EditText box.
// I've tried while (editText_HEX.length() < 7) as well, but still get a blank page
while (stringHEX.length() < 7){
}
Toast.makeText(getApplicationContext(), "text reached 7 characters", Toast.LENGTH_SHORT).show();
break;
}
}
I'm not getting any error in the logcat- the app works fine, it just doesn't show any of my widgets. If I delete the while loop, it works.
What I'm ultimately trying to get:
I'm trying to make an app that asks the user enter a hex value that will change the color of the background. In my previous question (which was answered), I figured out how to check for a valid hex. Now I want this loop running so that a person can enter a hex color into an EditText box, and the background color will instantly change; and if they re-enter a different hex into the textbox, the background will change once more. This while loop is just a simple program that I made to narrow down why my page was blank.
I've been working on different parts of an app in different projects. This is one- and then I'm planning on making the larger final app after I figure out the reasons for these errors and such. I'm new to programming for android, so if there is a simple fix to this I'd appreciate the help. Thanks!
Don't use a loop try this:
editText_HEX.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
// check for valid hex here
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
By default the length of the text in the stringHEX is 0. And in onCreate itself even before the layout is shown, you have a while loop which is checking the length of stringHEX. Since it becomes an infinite while loop, you are not getting anything on the screen. Just to test, give a dummy text to your stringHEX in your xml and it should work fine.

Loop Not performing as expected when using detachChild() and addChild()

This question refers to andengine GL-ES1.
I am having trouble making a wallpaper activity that refreshes when your return to it, or when the user performs actions in the game.
My game has two activities. In one, you can edit and arrange the background elements in a room. In the other you play the game, and it uses the same background with the elements you arranged in the first activity.
There is also a live wallpaper in which your room is the background and characters move around in front of it.
I am making updtaes in onResume() in the wallpaper.
first I detach all the backgroudn sprites i used before.
Then I attach new sprites in the updated positions.
What happens is: some of the sprites don't show up.
Here is the method: Can you see anything I'm doing wrong?
private void loadBackgroundDecorations() {
//Add new decorations
Log.d(TAG, "loadBackgoundDecorations");
mEngine.runOnUpdateThread(new Runnable() {
#Override
public void run() {
// Remove Old Decorations
Log.d(TAG, "loadBackgoundDecorations: decorationList.size() =" + decorationList.size());
while(decorationList.size() > 0){
Sprite d = decorationList.remove(0);
scene.detachChild(d);
Log.d(TAG, "loadBackgoundDecorations: detachChild");
}
decorationList.clear();
//Add new decorations
ArrayList<Integer> decorations = app.getBackgroundManager().getDecorations();
Log.d(TAG, "loadBackgoundDecorations: decorations.size()" +decorations.size());
for (int i = 0; i < decorations.size(); i+=3) {
Log.d(TAG, "Decoration Values: texture-"+decorations.get(i)+", x-"+decorations.get(1+i)+", y-"+decorations.get(2+i));
Sprite draggable = new Sprite(decorations.get(1+i),decorations.get(2+i),mGameTextureRegionLibrary.get(decorations.get(i)));
draggable.setIgnoreUpdate(true);
scene.attachChild(draggable,0);
decorationList.add(draggable);
Log.d(TAG, "loadBackgoundDecorations: attachChild"+ i);
}
}
});
}
#Override protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
BitmapTextureAtlasTextureRegionFactory.createFromAsset(mTexture, this, app.getAquariumBackground(), 0, 0);
addBubbles();
loadBackgroundDecorations();
addCharacters()
}
============ UPDATE =================
As some people have suggested below, I tried adding all the scene setup functions into the runnable. This has no effect. What has worked for me is to set the "wrong" decorations visible property to "false". But I am worried that this will eventually cause a memory leak as more and more duplicates of the sprites are hidden on the wallpaper.
The problem only exists when I call "detachChild". For some reason that seems to prevent "attachChild" from firing correcly. Anybody have ideas for what could be causing this?
Can anyone else create an activity that adds and removes sprites in the onResume function?
I am fairly certain that the error has to do with your onResume method. The order you have your methods in is
addBubbles();
loadBackgroundDecorations();
addCharacters()
but your loadBackgroundDecorations uses a runnable so there is no guarantee that the method will run in between.
My Explanation:
From what I understand both addCharacter and addBubbles will be running on the UIthread whereas the loadBackgroundDecorations method will run on the update thread. The two threads will go through the methods at different times and that is where you are seeing some inconsistencies.
To Fix:
Put addBubbles and addCharacters in the same runnable in the order that you want and it should work as expected.

Making images drop in android

I am making an android game which needs to display some different images.
I need to make a method that keeps on generating images from a resource in the drawable directory and then drop the images from the top of the screen to the bottom. I also need that each image should have an id "image-1" "image-2" in which the index number goes higher once more images are created as an integer. I also need them to be generated at different locations at the top of the screen and drop with a specified speed. Once they hit the bottom, I want a method to be executed like:
public void touchedGround() {
//My code
}
I am using this code so far:
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class GameScreenActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gamescreen);
generateParachuters(savedInstanceState);
}
private void generateParachuters(Bundle icicle) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "generating images", 10).show();
}
}
I know one way to do it, but it requires a lot more code then what you're probably looking for. But hey, here goes.
Create a class for your falling object, which I'm guessing is a Parachuter. This class will have an X and Y variable to keep track of where it is on the screen. You can then have a tick method, which will increase the Y variable by however fast you want it to fall. You can also have them keep track of a integer ID if you want.
Create a list that will hold the Parachuter objects. I use an ArrayList. This way you create a Parachuter when needed and add it to the list. Cycle through the list to draw each one.
You need something to draw the Parachuters with. Personally, I use Canvas from SurfaceView.
You'll need a looping animation. Loop through, each time drawing the Parachuters and calling tick on each one.
During the loop, you can check the position of each Parachuter. If its position goes beyond Canvas.getHeight(), remove the image from the list.
Well, that's quite a bit there. Ask me if you need further clarification.
UPDATE: Here's a fully-working example.
UPDATE 2:
//Check right edge of screen
for (int i = 0; i < parachuters.size(); i++)
{
if (parachuters.get(i).getX() > canvas.getWidth())
//Do whatever it is you want
}

Change a value smoothly increasing in speed by holding down a button

I have been steaming over this one a few days now. I try to have a selector for a big range of numbers... within int-limits. You ought to hold down a button and the value should change slow and the longer you press the more rapid it changes. You all know that kind of button, don't you?! :D
It has to be precise, yet fast to enter the number. I use a OnTouchListener. The event allows to .getDownTime().
I tried a lot, but always only got it to skip numbers (not really but too fast to use) or not repeatingly increase the value while holding down the button. If run without changes it is pretty fast, but it would be nice, if it starts to make 10 100 or 1000-jumps if it is held down long enough.
I prepared a little SSCCE looking like this:
public class ValueChangerSSCCE extends Activity implements OnTouchListener {
Button plusButton;
TextView valueView;
Button minusButton;
int value;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
plusButton = new Button(this);
plusButton.setText("+");
plusButton.setTextSize(120f);
plusButton.setOnTouchListener(this);
layout.addView(plusButton);
valueView = new TextView(this);
valueView.setGravity(Gravity.CENTER_HORIZONTAL);
valueView.setTextColor(Color.WHITE);
valueView.setText(value + "");
valueView.setTextSize(120f);
layout.addView(valueView);
minusButton = new Button(this);
minusButton.setText("-");
minusButton.setTextSize(120f);
minusButton.setOnTouchListener(this);
layout.addView(minusButton);
setContentView(layout);
}
/*
* Called when a button is pressed
*/
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v == plusButton) {
value++;
} else if (v == minusButton) {
value--;
}
valueView.setText(value + "");
return false;
}
}
For devices with low resolution one might have to decrease the text-sizes.
Thanks in advance!
Have a look at the NumberPicker source code. This is a widget from the SDK that does exactly what you are describing, except without the acceleration. Using post calls to a Handler as is done here is the best way to handle the timing events. The only addition you would need to make to this class is to vary the mSpeed value in the post callbacks (and perhaps the increment) based on the down time.
HTH.
The way I might try and tackle this is as follows:
Pressing + or - will start a Thread. The thread updates the number at a set interval by an offset value, if the number has changed more than 20 times then decrease the interval so the number updates faster, if the number is still changing a lot then the offset value would be made larger to skip numbers. Remember all this is happening in a thread.
When the user lifts their finger the thread is killed and the offset, interval is reset.
Use the value of getDownTime() to compute how big the counter increment should be.
First, design the response curve you would like. (That is, determine a function that defines how the value should change as a function of touch time and, perhaps, starting value. It does not — should not, from the way you describe it — be a straight line function.)
Then just make your increment follow the curve. It will probably help to store the button value and down time at the last event.

Categories