tjerkw / Android-SlideExpandableListView

A better ExpandableListView, with animated expandable views for each list item
Apache License 2.0
1.98k stars 741 forks source link

Scrolling hidden expanded item into the visible view #26

Closed naddaf closed 10 years ago

naddaf commented 11 years ago

Tjerk, The target has changed to 8 but the minSdk is still the same as before (1.6); changes are tested on 1.6 in emulator and it doesn't cause any issues there but the it takes effect only in froyo and above.

Ali.

tjerkw commented 11 years ago

Hi, could you reuse getAnimationDuration() instead of scrollAnimationDuration for the animation duration? Or could you explain me why a different durtion is needed? Otherwise the merge looks good.

B.t.w. i just accepted a different pull-request which affects the same file, so please update your code.

naddaf commented 11 years ago

I updated my fork, do I need to do a new Pull Request?

pommedeterresautee commented 11 years ago

Hi @naddaf , I have tested your fork, and it is not working correctly on my application.

When the the second layout is opened and hided at the same time, the listview is scrolled, but too much. IMO it should just scroll what is necessary to align the bottom of the view with the bottom of the listview.

I want to precise my item on the list view are really big, they look like "cards", may be it explains why the scroll effect is too much.

I have fixed it for my own app with this code:

In AbstractSlideExpandableListAdapter class

private void animateView(final View target, final int type) {
        Animation anim = new ExpandCollapseAnimation(
                target,
                type
        );
        anim.setDuration(getAnimationDuration());
        if (froyoOrAbove) {
            anim.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {}

                @Override
                public void onAnimationRepeat(Animation animation) {}

                @SuppressLint("NewApi")
                @Override
                public void onAnimationEnd(Animation animation) {
                    if (type == ExpandCollapseAnimation.EXPAND) {
                        if (parent instanceof ListView) {
                            centerfinalInListview(target, (ListView) parent);
                        }
                    }

                }
            });
        }
        target.startAnimation(anim);
    }

    /**
     * move the listview if one item is hidded
     *
     * @param l
     * @param v
     */
    private void centerfinalInListview(View v, ListView l) {
        int[] view = new int[2];
        v.getLocationOnScreen(view);

        WindowManager wm = (WindowManager) v.getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getMetrics(dm);
        int height = dm.heightPixels;
        if ((view[1] + v.getHeight()) > height) {
            l.smoothScrollBy((view[1]+v.getHeight()) - height, 1000);
        }
    }

It works for me because the listview is at the bottom of the screen, but this is OK only in my case. My code should be improved to work everywhere. Unfortunately I didn't find a reliable way to get the bottom of the listview...

Regards

satyadeepk commented 11 years ago

Hi @tjerkw, Any heads up on @naddaf 's pull request? Having this in the core project will be really helpful.

satyadeepk commented 11 years ago

@pommedeterresautee Your change works perfectly for me. :+1:
As you noted, it only works for cases where the listview is at the bottom of the screen.

xiaoli commented 11 years ago

Thanks @naddaf and @pommedeterresautee . I made changes to meet my requirement based on @pommedeterresautee code, the admob adview of SMART_BANNER occupies 50dp height on the bottom of screen, so I have to take that into account:

private void centerfinalInListview(View v, ListView l) {
        ...
        int height = dm.heightPixels - 50 * (dm.densityDpi / 160);
        ...
    }