Skip to content

maiwenchang/FooterView

Repository files navigation

FooterView

简书: https://github.com/maiwenchang/FooterView

实现FooterView的一种新思路,当FooterView距离屏幕顶部不超过一屏高度会自动消失。

  • image

Usage

放在RecyclerView下方即可:

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

   <android.support.v7.widget.RecyclerView
       android:id="@+id/recyclerView"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />

   <org.salient.autofooter.FooterView
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <include layout="@layout/layout_footer"/>

   </org.salient.autofooter.FooterView>

</LinearLayout>

Note: FooterView继承于FramLayout,本身不带视图,可以像上面的例子一样,在xml布局中加入视图,或者调用FooterView.addView(View child)添加视图,需要注意的是,FooterView只能添加一个直属子View。

Feel free to copy:

public class FooterView extends FrameLayout {

   public FooterView(@NonNull Context context) {
       super(context);
   }

   public FooterView(@NonNull Context context, @Nullable AttributeSet attrs) {
       super(context, attrs);
   }

   public FooterView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
       super(context, attrs, defStyleAttr);
   }

   @Override
   protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
       super.onLayout(changed, left, top, right, bottom);
       View child = getChildAt(0);
       if (child != null) {
           int heightPixels = getContext().getResources().getDisplayMetrics().heightPixels;
           int rawY = heightPixels - getRawTop(getParent());
           if (rawY > 0 && top > rawY) {//FooterView的顶部距离屏幕顶部超过一屏高度
               getChildAt(0).setVisibility(VISIBLE);
           } else {
               getChildAt(0).setVisibility(GONE);
           }
       }
   }

   //获取与屏幕顶部的距离
   private int getRawTop(ViewParent parent) {
       if (parent == null || ((ViewGroup) parent).getId() == Window.ID_ANDROID_CONTENT) {
           if (parent != null) {
               int[] position = new int[2];
               ((ViewGroup) parent).getLocationOnScreen(position);
               return position[1];
           }
           return 0;
       } else {
           return ((ViewGroup) parent).getTop() + getRawTop(parent.getParent());
       }
   }

   @Override
   public void addView(View child) {
       if (getChildCount() > 0) {
           throw new IllegalStateException("FooterView can host only one direct child");
       }

       super.addView(child);
   }

}

简单讲一下实现思路

要实现RecyclerView不满一屏不显示FooterView,关键在于如何知道RecyclerView不满一屏,当然RecyclerView上边还有ActionBarToolbar,状态栏等等,如果仅仅去比较RecyclerView的高度和屏幕高度,显然不可行。因此,产品经理心里想要的效果应当是应当是RecyclerView和状态栏等加起来铺不满一屏的时候,FooterView就不显示。

如果用传统的方式,需要把FooterView作为RecyclerView的一个Item去处理,并且把状态栏等高度考虑进去,以决定FooterView的是否显示内容。

这里尝试用一种新的方式去实现,就是让FooterView放在RecyclerView的下面,根据自己的位置自行决定要不要显示。实现步骤:
  • 1.新建一个类FooterView.class,让它继承自FramLayout
public class FooterView extends FrameLayout {

   public FooterView(@NonNull Context context) {
       super(context);
   }

   public FooterView(@NonNull Context context, @Nullable AttributeSet attrs) {
       super(context, attrs);
   }

   public FooterView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
       super(context, attrs, defStyleAttr);
   }
}
  • 2.重写onLayout()方法,在FooterView添加到布局或者布局发生变动时判断是否显示内容。
   @Override
   protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
       super.onLayout(changed, left, top, right, bottom);
       View child = getChildAt(0);
       if (child != null) {
           int heightPixels = getContext().getResources().getDisplayMetrics().heightPixels;
           int rawY = heightPixels - getRawTop(getParent());
           if (rawY > 0 && top > rawY) {//FooterView的顶部距离屏幕顶部超过一屏高度
               getChildAt(0).setVisibility(VISIBLE);
           } else {
               getChildAt(0).setVisibility(GONE);
           }
       }
   }
  • 3.利用递归获取与屏幕顶部的距离。
   //获取与屏幕顶部的距离
   private int getRawTop(ViewParent parent) {
       if (parent == null || ((ViewGroup) parent).getId() == Window.ID_ANDROID_CONTENT) {
           if (parent != null) {
               int[] position = new int[2];
               ((ViewGroup) parent).getLocationOnScreen(position);
               return position[1];
           }
           return 0;
       } else {
           return ((ViewGroup) parent).getTop() + getRawTop(parent.getParent());
       }
   }

About

实现FooterView的一种新思路,当距离屏幕顶部不超过一屏高度会自动消失。

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages