简体   繁体   中英

Android NestedScrollView has wrong size after app:layout_behavior

Since Google has published the design support library for android, there are many nice things that can be done without implementing custom code. While i've tested the custom views in this lib, i have found a worse thing, and i didn't know if this is a bug or not.

I have found the cheesesquare project on github. In the activity_detail.xml(layout file) there are 3 CardViews inside the NestedScrollView. If you delete 2 of them, you can see that the NestedScrollView doesn't have the full size of the parent(match_parent). The NestedScrollView is bound to the bottom of the parent view. http://i.stack.imgur.com/BXl7w.png

The NestedScrollView get's his full size when i remove the app:layout_behavior="@string/appbar_scrolling_view_behavior" .

But when i remove the layout behavior, the toolbar is not collapsing.

Is there any fix for this? Example layout file can be found here: https://github.com/Smove/cheesesquare/blob/stackoverflow/app/src/main/res/layout/activity_detail.xml

You can build the cheesesquare apk from my github branch stackoverflow

I had this problem and fixed adding:

android:layout_gravity="fill_vertical"

to the NestedScrollView. Then it starts behaving correctly, as I explained here also. Of course the NestedScrollView needs some kind of child (ie it must not be empty), otherwise the toolbar won't collapse.

Update

While this works well with small content, I noticed it has some problems showing longer contents, eg like the full activity_detail.xml above. The problem is that you can't scroll to the very bottom part of the content - it is unreachable at the bottom.

From my tests I could find that the missing part is as big as the collapsed toolbar (or at least that's what it looks to me). To fix this is issue, and having a solution reliable for both small and big contents, you should add a layout_marginBottom to the ScrollView, so that it gets measured and releases the missing bottom part. Thus:

android:layout_gravity="fill_vertical"
android:layout_marginBottom="?attr/actionBarSize"

or whatever size you gave to the Toolbar .

But still

Scrolling with small contents with this solution, even if the content is justly aligned at the top, isn't really smooth as scrolling with large contents. I'll use until a library fix comes.

Update2

Looks like this was fixed in v22.2.1 .

using the answer by @natario If you instead set a padding for the child (LinearLayout in my case) it will look better:

<androidx.core.widget.NestedScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"
                android:layout_gravity="fill_vertical">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:paddingBottom="?attr/actionBarSize">
                <!--Rest of the code-->

Or in Kotlin you can do something like this:

 coordinator.doOnLayout {
        nestedScrollView.minimumHeight = resources.displayMetrics.heightPixels - with(TypedValue().also {theme.resolveAttribute(android.R.attr.actionBarSize, it, true)}) {
            TypedValue.complexToDimensionPixelSize(data, resources.displayMetrics)}
    }

添加android:minHeight="?attr/actionBarSize"CollapsingToolbarLayout

Workaround

Before showing my NestedScrollView and after binding the data to the NestedScrollView content, I call the method fullScroll(int direction) of my NestedScrollView instance with the View.FOCUS_UP direction as argument.

Code example for a fragment:

NestedScrollView scrollView = (NestedScrollView) getActivity().findViewById(R.id.scroll_view); scrollView.fullScroll(View.FOCUS_UP);

use RecyclerView replace NestedScrollView fix this bug set item count 1,that ViewHolder return your real contentView;

my code:

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
    // 添加分割线
    recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext()));

    recyclerView.setAdapter(new Adapter<ViewHolder>() {

        @Override
        public int getItemCount() {
            return 1;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int arg1) {
            WebView view = (WebView) holder.itemView;
            view.getSettings().setJavaScriptEnabled(true);
            view.loadUrl("http://www.baidu.com");
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
            return new ViewHolder(inflater.inflate(R.layout.webview, arg0, false)) {
            };
        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM