3

As the title suggests, a LinearLayout in my app flickers randomly. It is hard to replicate and hard to get a screenshot at the same time. So please bear with me. I could only capture it by taking a picture. Here is the expected behavior of the LinearLayout (Notice the white box below the red header):

enter image description here

Now here is the same page with LinearLayout where the white background disappears:

enter image description here

There are two cases when this happens. First, after the page loads completely. Second, when doing drag events on the smiley faces.

To fix it, I tried to use the Android Studio's code analysis feature to get suggestions on how to further optimize this page's xml layout. The suggestions it gave were: Missing contentDescription attribute on image, alignment options to support right-to-left layouts, set baselineAligned="false" on LinearLayout for better performance.

I added the baselineAligned="false" option for all my LinearLayouts but nothing happened.

In previous posts here in SO, this is the closest I could get. However those cache options for LinearLayout doesn't seem to help. Do you think LinearLayout has optimizations too like what ListView have as described here? Most importantly, how can I solve the issue?

EDIT:

root.getViewTreeObserver().addOnGlobalLayoutListener(
     new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {    
            mWindowManager.updateViewLayout(mRootView,
                                mLayoutParams);

        }
});

To give more context, this app was implemented with services that has UI. The page in the screenshot is a service. (Please don't ask my why. I just joined the team and the original programmer already left.)

UPDATE: I found the issue! Hooray! So when the page loads, the first textbox automatically gets the focus. When I disabled the autofocus on my text field, the issue no longer happens. Can someone please tell me why?

Community
  • 1
  • 1
user1506104
  • 6,554
  • 4
  • 71
  • 89
  • Is it a standard LinearLayout? How do you set its background? What background is it? A png? A Drawable subclass? – natario Oct 27 '16 at 13:32
  • It is a standard LinearLayout with its children dynamically added. Its background is set using its XML attribute android:background=@drawable/white_rounded where white_rounded is of type shape, not PNG. Thanks for any suggestion you can give. – user1506104 Oct 28 '16 at 08:08
  • 4
    I am almost certain that you are redrawing (refreshing) whole layout on every change. That is almost always cause of flickering. Please paste parts of code to be sure. – Vladimir Jovanović Oct 28 '16 at 19:23
  • we can't help you unless you include the Java code and XML in your answer. – M D P Oct 30 '16 at 12:55
  • 1
    Create an emulator with a low memory, load your app to it and you will get a consistent/continuous flickering. – ozbek Oct 31 '16 at 01:44
  • @ozbek, i just tried in an emulator with 512mb RAM. The behavior was very the same. My test tablet specs is this: Galaxay Tab A6, 1.3GHz Quad Core, 1.5GB RAM. – user1506104 Oct 31 '16 at 06:21
  • @VladimirJovanović, i have this root.getViewTreeObserver().addOnGlobalLayoutListener(). then in its onGlobalLayoutListener, i have updateViewLayout. (I have edited my question to include this code.) I removed this to test, but issue still persists. – user1506104 Oct 31 '16 at 06:23

2 Answers2

1

I am pretty sure that mWindowManager.updateViewLayout(mRootView, mLayoutParams); is firing onGlobalLayout() method again, because updateViewLayout changes layout, and in documentation for onGlobalLayout() it says:

Callback method to be invoked when the global layout state or the visibility of views within the view tree changes.

So try adding root.getViewTreeObserver().removeGlobalOnLayoutListener(this); before mWindowManager.updateViewLayout(mRootView, mLayoutParams); to avoid recurrent calls of the same method.

UPDATE: Reason why it was happening on focus is because when TextView gets focus it changes background, and sometimes also size, so onGlobalLayout is called. If you remove listener everything should be fine.

Vladimir Jovanović
  • 2,261
  • 2
  • 24
  • 43
  • in the comments section, i mentioned that i tried removing the line `addOnGlobalLayoutListener()` but the issue persisted. so i think this is something else. thank you for this suggestion. (upvoting anyways as this is a good analysis) – user1506104 Nov 03 '16 at 05:39
0

I don't know but adding android:focusableInTouchMode="true" helped. I added this for my layouts which has editable fields in them such as

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:focusableInTouchMode="true">
    ...
    <EditText
        android:id="@+id/editText"
        android:layout_width="100dp"
        android:layout_height="wrap_content" />
    ...
 </LinearLayout>
user1506104
  • 6,554
  • 4
  • 71
  • 89