Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

java - Google maps flicker/blink black on toggling content visibility

I have implemented my map fragment with map as <fragment> in two places:

  1. (main) <DrawerLayout> --> <FrameLayout> (container)
    --> (fragment inflated) <CoordinatorLayout> --> <LinearLayout> --> <ViewPager2> (container)
    --> (fragment inflated) <NestedScrollView> --> <LinearLayout> --> <ViewPager2> (container)
    --> (map fragment inflated) <FrameLayout> --> <fragment>
  2. (main) <LinearLayout> --> <LinearLayout> (container)
    --> (fragment inflated) <LinearLayout> --> <ViewPager2> (container)
    --> (map fragment inflated) <FrameLayout> --> <fragment>

The problem is that in the first case my map flickers when I click on a map marker or when I click on an ImageView from my map fragment ViewGroup that does nothing but toggle icons visibility between GONE and VISIBLE. The second case works fine. It gives me a hint that map's blinking is due to other views changing their visibility in the NestedScrollView. Maybe it is also because of overwhelming number of parents.

I tried to implement android:layerType="hardware" but it doesnt help. Also, when the visibility is toggled between VISIBLE and INVISIBLE all works fine, but this is not the solution.

I have recorded the told map's behaviour and attached it here. On the record I click on a ToggleButton and toggle a small tick icon between GONE and VISIBLE.

Any ideas how to fix that?

Code

Main Activity

It is a Navigation Drawer Activity
public class MainActivityC extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_c);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_activity_c, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

Fragment 1

This fragment holds ViewPager2
public class GalleryFragment extends Fragment{


    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_gallery, container, false);
    }


    private Context context;
    private ViewPager2 viewPager2;
    private TabLayout tabLayout;


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        context = getActivity();
        initTab();
    }


    private void initTab() {

        viewPager2 = getView().findViewById(R.id.viewpager2_walks_saved);
        viewPager2.setAdapter(new WalksSavedPagerAdapter(getActivity()));
        viewPager2.setUserInputEnabled(false); // NO SCROLL
        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                switch (position) {
                    case 0:
                        String text1 = "Walks History";
                        ((MainActivityC) context).getSupportActionBar().setTitle(text1);
                        break;
                    case 1:
                        String text2 = "Walks Statistics";
                        ((MainActivityC) context).getSupportActionBar().setTitle(text2);
                        break;
                }
            }
        });

        tabLayout = getView().findViewById(R.id.tabLayout_walks_statistics);
        TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
                tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {

                switch (position) {
                    case 0:
                        tab.setText("Walks History");
                        break;
                    case 1:
                        tab.setText("Walks Statistics");
                        break;
                }

            }
        }
        );
        tabLayoutMediator.attach();
    }

}

Layout:

<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="160dp"
        android:background="?attr/colorPrimary">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|snap"
            android:elevation="4dp">

            <TextView
                android:id="@+id/drawer_fragment_saved_walks_info"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:text="Saved Walks"
                android:textSize="30sp"
                android:textColor="@color/white"
                android:layout_gravity="center"/>
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_height="0dp"
                android:layout_width="match_parent"
                app:layout_collapseMode="pin" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    <!--android:layout_height="?attr/actionBarSize"-->
    </com.google.android.material.appbar.AppBarLayout>


    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!--  Tab to chose between Saved Walks and Statistics -->
        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabLayout_walks_statistics"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent"
            android:layout_gravity="bottom"
            app:tabIndicatorHeight="3dp"
            app:tabMode="fixed"
            app:tabPaddingBottom="4dp"
            app:tabPaddingTop="4dp" />

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager2_walks_saved"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

Fragment 2

This fragment is shown in the ViewPager2 and has its own ViewPager2
public class StatisticsFragment extends Fragment {

    private ViewPager2 viewPager2;
    private TabLayout tabLayoutViewPager;
    private StatisticsPagerAdapter statisticsPagerAdapter;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_walks_statistics, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        init();
    }


    private void init(){

        statisticsPagerAdapter = new StatisticsPagerAdapter(getActivity());

        viewPager2 = getView().findViewById(R.id.viewpager2_statistics);
        viewPager2.setAdapter(statisticsPagerAdapter);
        viewPager2.setUserInputEnabled(false); // NO SCROLL


        tabLayoutViewPager = getView().findViewById(R.id.tabLayout_statistics);
        TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
                tabLayoutViewPager, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {

                switch (position) {
                    case 0:
                        tab.setText("Events");
                        break;
                    case 1:
                        tab.setText("Chronology");
                        break;
                    case 2:
                        tab.setText("Heat Map");
                        break;
                }

            }
        }
        );
        tabLayoutMediator.attach();

    }
}

Layout:

<androidx.core.widget.NestedScrollView
    android:id="@+id/heatmap_nested_scroll_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.material.t

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have solved my own problem, however other solutions are more than welcome.

The issue is that the map's parent <NestedScrollView> has android:fillViewport="true" attribute, which forces the view to stretch its content to fill the viewport.

The solution is to set the map's view to a constant height. So, android:layout_height="match_parent" should be changed to android:layout_height="500dp" for example. Also, the height could be set dinamically as appropriate.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...