底部的粘性 ScrollView 项目 - Android [英] Sticky ScrollView Item at the Bottom - Android

查看:24
本文介绍了底部的粘性 ScrollView 项目 - Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个粘在屏幕底部的粘性滚动视图项目.下面是几个屏幕截图来解释我的问题.

  1. 下面的屏幕显示了屏幕底部的固定视图/布局,上面写着保存到并添加到购物袋"

  1. 当用户向下滚动页面时,布局/视图会随着页面滚动.如下图所示.

我尝试过的事情:

1.StickyScrollViewItems by emisjolander:

布局 XML

 <?xml version="1.0" encoding="utf-8"?><LinearLayout 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:layout_width="match_parent"android:layout_height="56dp"android:background="@color/red">//修复产品名称的标题</RelativeLayout><滚动视图android:id="@+id/scroll_main"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="0.5"><线性布局android:id="@+id/lin_upper"android:layout_width="match_parent"android:layout_height="match_parent"机器人:方向=垂直">///对于您要放置在固定的底视图上侧边的内容>>就我而言,寻呼机、PagerIndicator、ProductName、Price、尺寸和尺寸列表>>//创建它以获得上层内容高度.. 并放置您的内容..</LinearLayout><线性布局android:id="@+id/llin_inner_button"android:layout_width="match_parent"android:layout_height="48dp"机器人:方向=水平"机器人:可见性=可见">//复制要粘贴的底视图</LinearLayout><文本视图android:id="@+id/txt_temp"android:layout_width="wrap_content"android:layout_height="wrap_content"机器人:layout_marginLeft="8dp"android:layout_marginTop="8dp"android:text="劳拉西泮属于一组药物"/></ScrollView><线性布局android:id="@+id/llin_outer_button"android:layout_width="match_parent"android:layout_height="48dp"机器人:方向=水平">//你实际的底部视图在这里...</LinearLayout></LinearLayout>

Java 文件

声明变量

 private int layout_height = 0;整数高度 = 0;

现在您需要根据设备屏幕高度获取高度,包括状态栏高度和软按钮高度,并且您需要将标题高度(如有必要)添加到总高度中.

 public int getStatusBarHeight() {整数结果 = 0;int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");如果(资源 ID > 0){结果 = getResources().getDimensionPixelSize(resourceId);}返回结果;}@SuppressLint("NewApi")私有 int getSoftButtonsBarHeight() {//getRealMetrics 仅适用于 API 17 和 +如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {DisplayMetrics 指标 = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);int usableHeight = metrics.heightPixels;getWindowManager().getDefaultDisplay().getRealMetrics(metrics);int realHeight = metrics.heightPixels;if (realHeight > usableHeight)返回 realHeight - 可用高度;别的返回0;}返回0;}公共 int pxToDp(int px) {DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();int dp = Math.round(px/(displayMetrics.xdpi/DisplayMetrics.DENSITY_DEFAULT));返回dp;}公共静态浮动dipToPixels(上下文上下文,浮动dipValue){DisplayMetrics 指标 = context.getResources().getDisplayMetrics();返回 TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dipValue,metrics);}

计算高度

 Display display = getWindowManager().getDefaultDisplay();点大小 = new Point();display.getSize(size);int 宽度 = size.x;如果(getSoftButtonsBarHeight()== 0){height = size.y - getStatusBarHeight() - getSoftButtonsBarHeight() - (int) dipToPixels(ProductDetailActivity.this, 104);} 别的 {height = size.y - getStatusBarHeight() - getSoftButtonsBarHeight() - (int) dipToPixels(ProductDetailActivity.this, 56);}Log.v("height_sc", height + "" + " " + getStatusBarHeight() + " " + getSoftButtonsBarHeight() + " " + size.y);ViewTreeObserver 观察者 = lin_upper.getViewTreeObserver();观察者.addOnGlobalLayoutListener(新的ViewTreeObserver.OnGlobalLayoutListener(){@覆盖公共无效 onGlobalLayout() {//TODO 自动生成的方法存根躺高度 = lin_upper.getHeight();int headerLayoutWidth = lin_upper.getWidth();lin_upper.getViewTreeObserver().removeGlobalOnLayoutListener(这个);Log.v("height",lay_height + "");}});

现在您需要在 onScrollChanged() 方法中实现滚动视图的功能.

 scroll_main.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {@覆盖公共无效 onScrollChanged() {new Handler().post(new Runnable() {@覆盖公共无效运行(){int scrollX = scroll_main.getScrollX();//对于水平滚动视图int scrollY = scroll_main.getScrollY();//对于垂直滚动视图int sc = scrollY + 高度;Log.v("bottom",lay_height + " Y=" + sc + " " + scrollY + " " + height);如果(sc>=lay_height){llin_outer_button.setVisibility(View.GONE);} 别的 {llin_outer_button.setVisibility(View.VISIBLE);}}});}});

I wanted to implement a sticky scrollview item which sticks at the bottom of the screen. Below are a couple of screenshots to explain my question.

  1. The below screen shows the fixed view/layout at the bottom of the screen saying 'Save to and Add to Bag'

  1. When the user scrolls down the page, the layout/view scrolls with the page. As shown in the below screen.

Things i have tried:

1.StickyScrollViewItems by emilsjolander: https://github.com/emilsjolander/StickyScrollViewItems/blob/master/library/src/com/emilsjolander/components/StickyScrollViewItems/StickyScrollView.java

I tried to reverse the header to the bottom, but no luck!

Your help will be deeply appreciated.

Thank you.

EDIT:

Following is the scrollview I tried to make. The sticky view still sticks at the top, where as it should stick to the bottom.

public class StickyScrollView extends ScrollView {

/**
 * Tag for views that should stick and have constant drawing. e.g. TextViews, ImageViews etc
 */
public static final String STICKY_TAG = "sticky";

/**
 * Flag for views that should stick and have non-constant drawing. e.g. Buttons, ProgressBars etc
 */
public static final String FLAG_NONCONSTANT = "-nonconstant";

/**
 * Flag for views that have aren't fully opaque
 */
public static final String FLAG_HASTRANSPARANCY = "-hastransparancy";

/**
 * Default height of the shadow peeking out below the stuck view.
 */
private static final int DEFAULT_SHADOW_HEIGHT = 10; // dp;

private ArrayList<View> stickyViews;
private View currentlyStickingView;
private float stickyViewTopOffset, stickViewBottomOffset;
private int stickyViewLeftOffset;
private boolean redirectTouchesToStickyView;
private boolean clippingToPadding;
private boolean clipToPaddingHasBeenSet;

private int mShadowHeight;
private Drawable mShadowDrawable;

private final Runnable invalidateRunnable = new Runnable() {

    @Override
    public void run() {
        if (currentlyStickingView != null) {
            int l = getLeftForViewRelativeOnlyChild(currentlyStickingView);
            int t = getBottomForViewRelativeOnlyChild(currentlyStickingView);
            int r = getRightForViewRelativeOnlyChild(currentlyStickingView);
            //int b = (int) (getScrollY() + (currentlyStickingView.getHeight() + stickyViewTopOffset));
            int b = getBottomForViewRelativeOnlyChild(currentlyStickingView);
            invalidate(l, t, r, b);
        }
        postDelayed(this, 16);
    }
};

public StickyScrollView(Context context) {
    this(context, null);
}

public StickyScrollView(Context context, AttributeSet attrs) {
    this(context, attrs, android.R.attr.scrollViewStyle);
}

public StickyScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    setup();

    TypedArray a = context.obtainStyledAttributes(attrs,
            R.styleable.StickyScrollView, defStyle, 0);

    final float density = context.getResources().getDisplayMetrics().density;
    int defaultShadowHeightInPix = (int) (DEFAULT_SHADOW_HEIGHT * density + 0.5f);

    mShadowHeight = a.getDimensionPixelSize(
            R.styleable.StickyScrollView_stuckShadowHeight,
            defaultShadowHeightInPix);

    int shadowDrawableRes = a.getResourceId(
            R.styleable.StickyScrollView_stuckShadowDrawable, -1);

    if (shadowDrawableRes != -1) {
        mShadowDrawable = context.getResources().getDrawable(
                shadowDrawableRes);
    }

    a.recycle();

}

/**
 * Sets the height of the shadow drawable in pixels.
 *
 * @param height
 */
public void setShadowHeight(int height) {
    mShadowHeight = height;
}


public void setup() {
    stickyViews = new ArrayList<View>();
}

private int getLeftForViewRelativeOnlyChild(View v) {
    int left = v.getLeft();
    while (v.getParent() != getChildAt(0)) {
        v = (View) v.getParent();
        left += v.getLeft();
    }
    return left;
}

private int getTopForViewRelativeOnlyChild(View v) {
    int top = v.getTop();
    while (v.getParent() != getChildAt(0)) {
        v = (View) v.getParent();
        top += v.getTop();
    }
    return top;
}

private int getRightForViewRelativeOnlyChild(View v) {
    int right = v.getRight();
    while (v.getParent() != getChildAt(0)) {
        v = (View) v.getParent();
        right += v.getRight();
    }
    return right;
}

private int getBottomForViewRelativeOnlyChild(View v) {
    int bottom = v.getBottom();
    while (v.getParent() != getChildAt(0)) {
        v = (View) v.getParent();
        bottom += v.getBottom();
    }
    return bottom;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    if (!clipToPaddingHasBeenSet) {
        clippingToPadding = true;
    }
    notifyHierarchyChanged();
}

@Override
public void setClipToPadding(boolean clipToPadding) {
    super.setClipToPadding(clipToPadding);
    clippingToPadding = clipToPadding;
    clipToPaddingHasBeenSet = true;
}

@Override
public void addView(View child) {
    super.addView(child);
    findStickyViews(child);
}

@Override
public void addView(View child, int index) {
    super.addView(child, index);
    findStickyViews(child);
}

@Override
public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
    super.addView(child, index, params);
    findStickyViews(child);
}

@Override
public void addView(View child, int width, int height) {
    super.addView(child, width, height);
    findStickyViews(child);
}

@Override
public void addView(View child, android.view.ViewGroup.LayoutParams params) {
    super.addView(child, params);
    findStickyViews(child);
}

@Override
protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    if (currentlyStickingView != null) {
        canvas.save();
        //canvas.translate(getPaddingLeft() + stickyViewLeftOffset, getScrollY() + stickyViewTopOffset + (clippingToPadding ? getPaddingTop() : 0));
        canvas.translate(getPaddingLeft() + stickyViewLeftOffset, getScrollY() - stickViewBottomOffset + (clippingToPadding ? getPaddingBottom() : 0));

        //canvas.clipRect(0, (clippingToPadding ? -stickyViewTopOffset : 0),
        //getWidth() - stickyViewLeftOffset,
        //currentlyStickingView.getHeight() + mShadowHeight + 1);

        canvas.clipRect(0, currentlyStickingView.getHeight() - mShadowHeight, getWidth() - stickyViewLeftOffset, (clippingToPadding ? 0 : stickViewBottomOffset));

        if (mShadowDrawable != null) {
            int left = 0;
            int right = currentlyStickingView.getWidth();
            int top = currentlyStickingView.getHeight();
            int bottom = currentlyStickingView.getHeight() + mShadowHeight;
            mShadowDrawable.setBounds(left, top, right, bottom);
            mShadowDrawable.draw(canvas);
        }

        //canvas.clipRect(0, (clippingToPadding ? -stickyViewTopOffset : 0), getWidth(), currentlyStickingView.getHeight());
        canvas.clipRect(0, currentlyStickingView.getHeight(), getWidth(), (clippingToPadding ? 0 : stickViewBottomOffset));
        if (getStringTagForView(currentlyStickingView).contains(FLAG_HASTRANSPARANCY)) {
            showView(currentlyStickingView);
            currentlyStickingView.draw(canvas);
            hideView(currentlyStickingView);
        } else {
            currentlyStickingView.draw(canvas);
        }
        canvas.restore();
    }
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        redirectTouchesToStickyView = true;
    }

    if (redirectTouchesToStickyView) {
        redirectTouchesToStickyView = currentlyStickingView != null;
        if (redirectTouchesToStickyView) {
            redirectTouchesToStickyView =
                    //ev.getY() <= (currentlyStickingView.getHeight() + stickyViewTopOffset)
                    ev.getY() <= (currentlyStickingView.getHeight() - stickViewBottomOffset) &&
                            ev.getX() >= getLeftForViewRelativeOnlyChild(currentlyStickingView) &&
                            ev.getX() <= getRightForViewRelativeOnlyChild(currentlyStickingView);
        }
    } else if (currentlyStickingView == null) {
        redirectTouchesToStickyView = false;
    }
    if (redirectTouchesToStickyView) {
        //ev.offsetLocation(0, -1 * ((getScrollY() + stickyViewTopOffset) - getTopForViewRelativeOnlyChild(currentlyStickingView)));
        ev.offsetLocation(0, 1 * ((getScrollY() + stickViewBottomOffset) - getBottomForViewRelativeOnlyChild(currentlyStickingView)));
    }
    return super.dispatchTouchEvent(ev);
}

private boolean hasNotDoneActionDown = true;

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (redirectTouchesToStickyView) {
        //ev.offsetLocation(0, ((getScrollY() + stickyViewTopOffset) - getTopForViewRelativeOnlyChild(currentlyStickingView)));
        ev.offsetLocation(0, ((getScrollY() - stickViewBottomOffset) - getTopForViewRelativeOnlyChild(currentlyStickingView)));
    }

    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        hasNotDoneActionDown = false;
    }

    if (hasNotDoneActionDown) {
        MotionEvent down = MotionEvent.obtain(ev);
        down.setAction(MotionEvent.ACTION_DOWN);
        super.onTouchEvent(down);
        hasNotDoneActionDown = false;
    }

    if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
        hasNotDoneActionDown = true;
    }

    return super.onTouchEvent(ev);
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);
    doTheStickyThing();
}

private void doTheStickyThing() {
    View viewThatShouldStick = null;
    View approachingView = null;
    for (View v : stickyViews) {
        int viewTop = getTopForViewRelativeOnlyChild(v) - getScrollY() + (clippingToPadding ? 0 : getPaddingTop());
        int viewBottom = getBottomForViewRelativeOnlyChild(v) - getScrollY() + (clippingToPadding ? 0 : getPaddingBottom());
        Log.e("VIEW BOTTOM: ", "VIEW BOTTOM: " + viewBottom);

        //Log.e("VIEW TOP: ", "VIEW TOP: " + viewTop);

        //BOTTOM
        if (viewBottom >= 0) {
            if (viewThatShouldStick == null || viewBottom > (getBottomForViewRelativeOnlyChild(viewThatShouldStick) - getScrollY() + (clippingToPadding ? 0 : getPaddingBottom()))) {
                viewThatShouldStick = v;
                Log.e("VIEW BOTTOM: ", "VIEW THAT SHOULD STICK: " + viewThatShouldStick);
            }
        } else {
            if (approachingView == null || viewBottom < (getBottomForViewRelativeOnlyChild(approachingView) - getScrollY() + (clippingToPadding ? 0 : getPaddingBottom()))) {
                approachingView = v;
                Log.e("VIEW BOTTOM: ", "APPROACHING VIEW: " + approachingView);
            }
        }

        //            //TOP
        //            if (viewTop <= 0) {
        //                if (viewThatShouldStick == null || viewTop > (getTopForViewRelativeOnlyChild(viewThatShouldStick) - getScrollY() + (clippingToPadding ? 0 : getPaddingTop()))) {
        //                    viewThatShouldStick = v;
        //                }
        //            } else {
        //                if (approachingView == null || viewTop < (getTopForViewRelativeOnlyChild(approachingView) - getScrollY() + (clippingToPadding ? 0 : getPaddingTop()))) {
        //                    approachingView = v;
        //                }
        //            }
    }

    //BOTTOM
    if (viewThatShouldStick != null) {
        stickViewBottomOffset = approachingView == null ? 0 : Math.min(0, getBottomForViewRelativeOnlyChild(approachingView) - getScrollY() + (clippingToPadding ? 0 : getPaddingBottom() - viewThatShouldStick.getHeight()));
        if (viewThatShouldStick != currentlyStickingView) {
            if (currentlyStickingView != null) {
                stopStickingCurrentlyStickingView();
                Log.e("BOTTOM UNSTUCK: ", "BOTTOM UNSTUCK: ");
            }
            stickyViewLeftOffset = getLeftForViewRelativeOnlyChild(viewThatShouldStick);
            startStickingView(viewThatShouldStick);
            Log.e("BOTTOM STUCK: ", "BOTTOM STUCK: " + viewThatShouldStick);
        }
    } else if (currentlyStickingView != null) {
        Log.e("BOTTOM UNSTUCK: ", "BOTTOM UNSTUCK: ");
        stopStickingCurrentlyStickingView();
    }

    //TOP
    //        if (viewThatShouldStick != null) {
    //            stickyViewTopOffset = approachingView == null ? 0 : Math.min(0, getTopForViewRelativeOnlyChild(approachingView) - getScrollY() + (clippingToPadding ? 0 : getPaddingTop()) - viewThatShouldStick.getHeight());
    ////            Log.e("VIEW TOP: ", "STICKY VIEW TOP OFFSET: " + stickyViewTopOffset);
    //            if (viewThatShouldStick != currentlyStickingView) {
    //                if (currentlyStickingView != null) {
    //                    stopStickingCurrentlyStickingView();
    //                }
    //                // only compute the left offset when we start sticking.
    //                stickyViewLeftOffset = getLeftForViewRelativeOnlyChild(viewThatShouldStick);
    //                startStickingView(viewThatShouldStick);
    //            }
    //        } else if (currentlyStickingView != null) {
    //            stopStickingCurrentlyStickingView();
    //        }
}

private void startStickingView(View viewThatShouldStick) {
    currentlyStickingView = viewThatShouldStick;
    if (getStringTagForView(currentlyStickingView).contains(FLAG_HASTRANSPARANCY)) {
        hideView(currentlyStickingView);
    }
    if (((String) currentlyStickingView.getTag()).contains(FLAG_NONCONSTANT)) {
        post(invalidateRunnable);
    }
}

private void stopStickingCurrentlyStickingView() {
    if (getStringTagForView(currentlyStickingView).contains(FLAG_HASTRANSPARANCY)) {
        showView(currentlyStickingView);
    }
    currentlyStickingView = null;
    removeCallbacks(invalidateRunnable);
}

/**
 * Notify that the sticky attribute has been added or removed from one or more views in the View hierarchy
 */
public void notifyStickyAttributeChanged() {
    notifyHierarchyChanged();
}

private void notifyHierarchyChanged() {
    if (currentlyStickingView != null) {
        stopStickingCurrentlyStickingView();
    }
    stickyViews.clear();
    findStickyViews(getChildAt(0));
    doTheStickyThing();
    invalidate();
}

private void findStickyViews(View v) {
    if (v instanceof ViewGroup) {
        ViewGroup vg = (ViewGroup) v;
        for (int i = 0; i < vg.getChildCount(); i++) {
            String tag = getStringTagForView(vg.getChildAt(i));
            if (tag != null && tag.contains(STICKY_TAG)) {
                stickyViews.add(vg.getChildAt(i));
            } else if (vg.getChildAt(i) instanceof ViewGroup) {
                findStickyViews(vg.getChildAt(i));
            }
        }
    } else {
        String tag = (String) v.getTag();
        if (tag != null && tag.contains(STICKY_TAG)) {
            stickyViews.add(v);
        }
    }
}

private String getStringTagForView(View v) {
    Object tagObject = v.getTag();
    return String.valueOf(tagObject);
}

private void hideView(View v) {
    if (Build.VERSION.SDK_INT >= 11) {
        v.setAlpha(0);
    } else {
        AlphaAnimation anim = new AlphaAnimation(1, 0);
        anim.setDuration(0);
        anim.setFillAfter(true);
        v.startAnimation(anim);
    }
}

private void showView(View v) {
    if (Build.VERSION.SDK_INT >= 11) {
        v.setAlpha(1);
    } else {
        AlphaAnimation anim = new AlphaAnimation(0, 1);
        anim.setDuration(0);
        anim.setFillAfter(true);
        v.startAnimation(anim);
    }
}
}

解决方案

I have the same requirement to implement this kind of view and i have figured out solution as per my code and logic. So you can apply code which i am sharing with you!

Below is the my project image how it is working using my code.

Layout XML

  <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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:background="@color/white"
        android:orientation="vertical">
     <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="@color/red">


// Fix header For Product Name

</RelativeLayout>
         <ScrollView
                android:id="@+id/scroll_main"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="0.5">

        <LinearLayout
                        android:id="@+id/lin_upper"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:orientation="vertical">

        /// For the Conternt that you want to put upper Side OF bottom View that is Fix>> In my case pager, PagerIndicator ,ProductName, Price ,Size And size list>>

        // Create this to get Upper Content height.. And Put your Content..


        </LinearLayout>
         <LinearLayout
                        android:id="@+id/llin_inner_button"
                        android:layout_width="match_parent"
                        android:layout_height="48dp"
                        android:orientation="horizontal"
                        android:visibility="visible">

        // Copy Bottom View that you want to Stick

        </LinearLayout>
         <TextView
                        android:id="@+id/txt_temp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="8dp"
                        android:layout_marginTop="8dp"
                        android:text="Lorazepam belongs to a group of drugs"/>

        </ScrollView>

        <LinearLayout
                android:id="@+id/llin_outer_button"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:orientation="horizontal">

        // Your actual BottomView Here...

        </LinearLayout>

    </LinearLayout>

Java File

Declare your variables

 private int lay_height = 0;
 int height = 0;

Now you need to get your height as per device screen height including status bar height and soft buttons height and you need to add header height(if necessary) in to total height.

 public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

@SuppressLint("NewApi")
private int getSoftButtonsBarHeight() {
    // getRealMetrics is only available with API 17 and +
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int usableHeight = metrics.heightPixels;
        getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
        int realHeight = metrics.heightPixels;
        if (realHeight > usableHeight)
            return realHeight - usableHeight;
        else
            return 0;
    }
    return 0;
}

public int pxToDp(int px) {
    DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
    int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
    return dp;
}

public static float dipToPixels(Context context, float dipValue) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
}

Calculate Height

    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int width = size.x;


    if (getSoftButtonsBarHeight() == 0) {
        height = size.y - getStatusBarHeight() - getSoftButtonsBarHeight() - (int) dipToPixels(ProductDetailActivity.this, 104);

    } else {
        height = size.y - getStatusBarHeight() - getSoftButtonsBarHeight() - (int) dipToPixels(ProductDetailActivity.this, 56);
    }

    Log.v("height_sc", height + "" + "   " + getStatusBarHeight() + "  " + getSoftButtonsBarHeight() + "   " + size.y);

    ViewTreeObserver observer = lin_upper.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            // TODO Auto-generated method stub
            lay_height = lin_upper.getHeight();
            int headerLayoutWidth = lin_upper.getWidth();
            lin_upper.getViewTreeObserver().removeGlobalOnLayoutListener(
                    this);

            Log.v("height", lay_height + "");
        }
    });

Now you need to implement functionality for scroll view in onScrollChanged() method.

 scroll_main.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {

        @Override
        public void onScrollChanged() {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    int scrollX = scroll_main.getScrollX(); //for horizontalScrollView
                    int scrollY = scroll_main.getScrollY(); //for verticalScrollView


                    int sc = scrollY + height;

                    Log.v("bottom", lay_height + "  Y=" + sc + "  " + scrollY + "   " + height);

                    if (sc >= lay_height) {

                        llin_outer_button.setVisibility(View.GONE);

                    } else {
                        llin_outer_button.setVisibility(View.VISIBLE);
                    }
                }
            });
        }
    });

这篇关于底部的粘性 ScrollView 项目 - Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆