0
votes

In my testing code app I have a problem with setting if statement with getVisibility in it.

Basicaly, app should reveal (from GONE to VISIBLE) 1 TextView tv1, and then reveal 1 LinearLayout LL1 with 2 Buttons inside it btn1 & btn2. When either is pressed, LL1 should disappear (from VISIBLE back to GONE) and in its place, new tv2 or tv3 should appear (from GONE to VISIBLE) depending on which button is pressed. tv4 should wait until LL1 is GONE, and then appear. A 1s interval is set between appearances.

Everything runs ok, until IF part which doesnt work. I have also tried

if (btn1.isPressed() || btn2.isPressed())

and

if (tv2.getVisibility()==View.VISIBLE || tv3.getVisibility()==View.VISIBLE)

but it didnt work. I guess the problem is the way I acces getVisibility.

I even tryed defining global boolean x=false;, and then in OnClickListener setting x=true; but then if (x) {... returns false!?

HOW TO MAKE IF STATEMENT WORK!?

Everything (tv1..tv4, btn1, btn2, LL1) in layout file is predefined and inittialy set to GONE. This is my activity>

 @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.test_layout);
            Thread mainThread = new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                             startApp();
                        }
                    }
            );
            mainThread.start();
        }

public void startApp() {
        Button btn1 = (Button) findViewById(R.id.btn1);
        Button btn2 = (Button) findViewById(R.id.btn2);
        TextView tv1 = (TextView) findViewById(R.id.line1);
        TextView tv2 = (TextView) findViewById(R.id.line2);
        TextView tv3 = (TextView) findViewById(R.id.line3);
        TextView tv4 = (TextView) findViewById(R.id.line4);
        LinearLayout LL1 = (LinearLayout) findViewById(R.id.LL1);

        show_line(tv1, 1000);
        btnLL(LL1, btn1, btn2, tv2, tv3);

        //THIS IS THE PROBLEM IT ALWAYS RETURNS TRUE
        if (LL1.getVisibility()==View.GONE) show_line(tv4, 1000);
}

public void show_line (final TextView tv, int duration) {
        try {
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        tv.getHandler().post(new Runnable() {
            public void run() {
                tv.setVisibility(View.VISIBLE);
            }
        });
        /*tv.setVisibility(View.VISIBLE); CANT USE THIS BECAUSE IM NOT IN UI THREAD*/
}

public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {

        //LL.setVisibility(View.VISIBLE); AGAIN NOT IN UI THREAD
        LL.getHandler().post(new Runnable() {
            public void run() {
                LL.setVisibility(View.VISIBLE);
            }
        });

        btnLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LL.getHandler().post(new Runnable() {
                    public void run() {
                        LL.setVisibility(View.GONE);
                    }
                });
                tvLeft.getHandler().post(new Runnable() {
                    public void run() {
                        tvLeft.setVisibility(View.VISIBLE);
                    }
                });
            }
        });

        btnRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LL.getHandler().post(new Runnable() {
                    public void run() {
                        LL.setVisibility(View.GONE);
                    }
                });
                tvRight.getHandler().post(new Runnable() {
                    public void run() {
                        tvRight.setVisibility(View.VISIBLE);
                    }
                });

            }
        });
}
2
Why are you using thread and post() ? You can remove everything, since all operation should be in UI thread. If you want to delay the transition from GONE to VISIBLE, use the Animation - GVillani82
1) Im new to all this android stuff :) 2) I read that you should use your own thread 3) How do you use animation in this case? 4) There is gonna be a lot more of what I posted here in an actual app 5) How can you use sleep in case you dont use thread? 6) I would still like to figure out the problem for this piece of code 7) Maybe the better option is to synchronize the methods!? (synchronize/wait/notify) - Nemanja
OK, I kind of solved this with my "primitive" solution, but please if someone know how to fix this code, and why this IF isn't working, post your answer just so I could fill my knowledge gap :) Anyways, before I tried to solve this with synchronization, I declared a global boolean x=false; then in onClick for both buttons at the very end I added x=true; and instead of IF I used while(!x) {} an empty loop so it would wait for action from btnLL() method. In the beggining of show_line() method I added if (x==true) x=false; and it worked like I wanted it. - Nemanja

2 Answers

0
votes
    //THIS IS THE PROBLEM IT ALWAYS RETURNS TRUE
    if (LL1.getVisibility()==View.GONE) show_line(tv4, 1000);

most likely because it has not been rendered yet, thus not visible yet.

You will need to place that check in something like this:

    LL1.getHandler().post(new Runnable() {
        public void run() {
            if (LL1.getVisibility()==View.GONE) show_line(tv4, 1000);
        }
    });

Which will wait for LL1 to be rendered/visible, before checking for getVisibility().

note: like GVillani82 said, you are unnecessarily using threads and posts. You don't really need Thread mainThread = new Thread() (and along with those view.getHandler().post()), only some view.post().

0
votes

OK, just as I wrote a comment with my "primitive" solution, I realized the problem, tested it and confirmed :) Why that IF didn't work...

execution steps:
1) show_line() gets from GONE to VISIBLE
2) btnLL() gets from GONE to VISIBLE and sets up 2 buttons with their onClick()
3) this is the important part
this is where the user should interact with app and make a choice so onClick could execute and then 4) IF statement should execute.
What actually happened is that IF statement executed before user interaction so, the LL1 was still VISIBLE, therefore if (LL1.getVisible()==View.GONE) returned false, and by the time user presses the button and LL1 switches to GONE, IF is already executed and doesn't check any more.