All Projects → rexyren → Widgetlayout

rexyren / Widgetlayout

自定义ViewGroup的集合(有 kotlin 实现分支):提高编写效率和 UI 绘制性能,少嵌套,易用易扩展。

Projects that are alternatives of or similar to Widgetlayout

FastBanner
🔥快速轮播图,支持自定义布局和使用自有图片显示组件
Stars: ✭ 27 (-79.23%)
Mutual labels:  layout, viewpager
Wormtabstrip
🐛 WormTabStrip ViewPager for iOS written in Swift, which gives continuous feedback to the user when scrolling
Stars: ✭ 145 (+11.54%)
Mutual labels:  viewpager, scrollview
Overscroll Decor
Android: iOS-like over-scrolling effect applicable over almost all scrollable Android views.
Stars: ✭ 2,671 (+1954.62%)
Mutual labels:  viewpager, scrollview
Containercontroller
UI Component. This is a copy swipe-panel from app: Apple Maps, Stocks. Swift version
Stars: ✭ 273 (+110%)
Mutual labels:  layout, scrollview
Flowhelper
帮助您迅速构建顶部Tab,比如今日头条效果,热搜、搜索记录、与ViewPager/ViewPager2搭配的工具类;
Stars: ✭ 295 (+126.92%)
Mutual labels:  viewpager, label
Txscrolllabelview
🌭TXScrollLabelView, the best way to show & display information such as adverts / boardcast / onsale e.g. with a customView.
Stars: ✭ 714 (+449.23%)
Mutual labels:  scrollview, label
Bubbletab
Put some bubble in your tabs and give your apps a supa fresh style !
Stars: ✭ 537 (+313.08%)
Mutual labels:  layout, viewpager
Bannerlayout
Support unlimited picture rotation BannerLayout, the minimum implementation of the code banner
Stars: ✭ 92 (-29.23%)
Mutual labels:  layout, viewpager
React Page Layout
Create layouts for react
Stars: ✭ 117 (-10%)
Mutual labels:  layout
Jxsegmentedview
A powerful and easy to use segmented view (segmentedcontrol, pagingview, pagerview, pagecontrol, categoryview) (腾讯新闻、今日头条、QQ音乐、网易云音乐、京东、爱奇艺、腾讯视频、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图)
Stars: ✭ 1,905 (+1365.38%)
Mutual labels:  scrollview
Flexlib
FlexLib是一个基于flexbox模型,使用xml文件进行界面布局的框架,融合了web快速布局的能力,让iOS界面开发像写网页一样简单快速
Stars: ✭ 1,569 (+1106.92%)
Mutual labels:  layout
Flutter Animations
Flutter animation tutorials, such common animation, flare animation.
Stars: ✭ 119 (-8.46%)
Mutual labels:  layout
Xbanner
🔥【图片轮播】支持图片无限轮播,支持AndroidX、自定义指示点、显示提示文字、切换动画、自定义布局,一屏显示多个等功能
Stars: ✭ 1,734 (+1233.85%)
Mutual labels:  viewpager
Stack Up.js
Create fixed width, variable height grid layouts.
Stars: ✭ 117 (-10%)
Mutual labels:  layout
Shviewpager
A simple view pager for iOS. Compatible with iOS 8.0 or later.
Stars: ✭ 127 (-2.31%)
Mutual labels:  viewpager
Column Setter
Custom responsive grids in Sass that work in older browsers.
Stars: ✭ 117 (-10%)
Mutual labels:  layout
Draggablemenu
A draggable menu that shows a thumbnail preview of an image grid
Stars: ✭ 117 (-10%)
Mutual labels:  layout
Involt
Inject hardware interactions directly into HTML layout.
Stars: ✭ 128 (-1.54%)
Mutual labels:  layout
Xrefreshlayout
【已过时,不再更新,请使用更强大的SmartRefreshLayout!】A refresh layout(无侵入下拉刷新和加载布局), can refresh RecyclerView for all LayoutManager, NestedScrollView。
Stars: ✭ 127 (-2.31%)
Mutual labels:  refreshlayout
Greedo Layout For Android
Full aspect ratio grid LayoutManager for Android's RecyclerView
Stars: ✭ 1,588 (+1121.54%)
Mutual labels:  layout

WidgetLayout 介绍(文档没有代码变更而更新)

WidgetLayout是一组高效自定义容器集合,支持限定最大最小宽高、按百分比、权重测绘,整体内容支持按gravity属性展示,可控制边界描边绘制和子 View 间水平和垂直分割线等,目前实现了以下容器(kotlin 实现见kotlin_master分支):

  1. ColumnLayout 以等分列方式布局,每列可设置内容居左,中,右,及铺满,可设置最小最大列宽高限定。
  2. WrapLayout 自适应换行容器,可限定每行最少和最多Item数,行内容可水平和垂直居中,在单行或列时支持weight权重属性,。
  3. ScrollLayout 滑动容器,可安全取代水平和垂直的ScrollView实现了NestedScrollingChild 接口。
  4. PageScrollView 扩展于ScrollLayout可水平垂直方向布局和滑动吸顶等,支持ScrollViewViewPager的交互方式和接口。
  5. NestRefreshLayout 具有可定制性的下拉刷新和加载更多容器,支持任意类型可滚动View,可添加头部和尾部且可设置悬停模式。
  6. NestFloatLayout 支持列表的嵌套滑动和指定子 View 悬停顶部,类似NestScrollView
  7. PageScrollTab 扩展于PageScrollView支持Tab场景交互和各种UI定制。
  8. LabelLayout 扩展于 WrapLayout,以ItemProvider 方式提供内容,有简单的回收复用机制,有Item点击监听。
  9. HierarchyLayout 调试容器可展示 View树层级关系和3D层级图。

以下是各容器实现的结构类图, 直接看示例请点击演示效果

WrapLayout&LabelLayout

实现背景及使用场景

1. 现有系统容器下开发界面经常遇到以下尴尬问题:

  • 实现特定的组合布局,我们会用功能鲜明的4大常用布局去嵌套实现,增加了严重OverDraw的机率
  • RelativeLayout 布局功能强大但是measure过程复杂(每次执行onMeasure 所有直接子View会有两次measure)
  • 为实现复杂交互工作量比开发业务繁重,比如滑动控件的悬停或联动
  • 分割线或是边界线很多人常用View来实现,即耗内存,又影响测绘时间。
  • 等分布局,使用多层不同方向LinearLayout来实现,嵌套太多。
  • 常用容器控件还没有对自身做最大宽高限定的,也无对子 View 做最大宽高限定。

2. 适合的使用场景举例按需要选择,可减少布局嵌套和复杂的交互代码。

  • 容器自身或对直接子View的最大宽高限定,容器内容和直接子Viewgravity灵活支持。
  • 容器需要描边或子View间画分割线的,或有各种间距要求,或按下自带激变层效果可使用继承于PressViewGroup的容器,如WrapLayout,LabelLayout,ColumnLayout
  • 常见的表格布局或动态等分布局可用ColumnLayout,支持每列的Align方式(左中右上下)和全铺满。
  • 水平或垂直布局,标签布局,或需自适应换行可选用WrapLayoutLabelLayout,可设置行最少最多的View 个数和行居中,
  • 列表需要嵌套滑动和悬停吸顶可用NestFloatLayout,类似NestScrollView 。
  • PageScrollView 可取代ScrollView&HorizontalScrollView 少嵌套,可设置任意子View滑动悬停在开始和结束位置,可不限定子View大小像 ViewPager 一样选中居中和滑动的交互。
  • WrapLayout,ColumnLayout是完全可替代支持不同方向的LinearLayout并能提供更多的布局约束,和背景,描边,分割等额外装饰
  • 以上容器都有一个共通的基类,便于统一监控性能打点如layout,measure过程等。

Demo演示效果

WrapLayoutLabelLayout ColumnLayout的演示效果。的演示效果。

WrapLayout&LabelLayout ColumnLayout


PageScrollViewPageScrollTab的使用示例。

无需嵌套LinearLayout > scrollview.gif ViewPager 模式 > viewpager.gif


Demo 入口 和 NestFloatLayout的演示效果。

NestFloatLayout NestFloatLayout


HiearchyLayout的静态图,实际是可随手势改变 3D 形态的。

hierarchyview [层级3D图] hierarchyviewnode [层级关系树]

如何使用:XML 属性和 API 简介

###集成需要提供support-v4包,然后再gradle 脚本中添加依赖如下。

 compile 'com.rexy.android:widgetlayout:1.0.1'

通用属性说明和介绍

注;所有xml 中使用自定义属性的地方,请在根标签中加上xmlns:app="http://schemas.android.com/apk/res-auto"

1. 所有容器自身和子 View 对于 maxWidth,maxHeight,gravity,widthPercent,heightPercent 支持。

a. 容器控件自身标签下使用 android:gravity,android:maxWidth ,android:maxHeight,即可支持容器内容的align 属和最大宽与高的限制。 java 代码可通过 setGravity ,setMaxWidth,setMaxHeight 来支持。

b. 容器直接子View使用android:layout_gravity,android:maxWidth,android:maxHeight 即可支持直接子View在容器内的Align和自身大小的限制。 java 代码可通过 BaseViewGroup.LayoutParams lp=(BaseViewGroup.LayoutParams)child.getLayoutParams(); lp.gravity=Gravity.CENTER;lp.maxWidth=100;lp.maxHeight=200

2. 部分容器FloatDrawableBorderDivider的应用,仅限于继承于PressViewGroup的容器

a. xml 中使用支持FloatDrawable属性和解释如下,java 都有对应的set 和get 方法:

  -hover drawable 忽略手势滑动到自身之外取消按下状态-->
  <attr name="ignoreForegroundStateWhenTouchOut" format="boolean"/>
  <!--hover drawable 颜色-->
  <attr name="foregroundColor" format="color"/>
  <!--hover drawable  圆角-->
  <attr name="foregroundRadius" format="dimension"/>
  <!--hover drawable 动画时间-->
  <attr name="foregroundDuration" format="integer"/>
  <!--hover drawable 最小不透明度-->
  <attr name="foregroundAlphaMin" format="integer"/>
  <!--hover drawable 最大不透明度-->
  <attr name="foregroundAlphaMax" format="integer"/>

b. xml 中使用支持BorderDivider属性和解释如下,java 都有对应的set 和get 方法:

  <!--左边线的drawable,颜色,宽度,和边线padding-->
  <attr name="borderLeft" format="reference"/>
  <attr name="borderLeftColor" format="color"/>
  <attr name="borderLeftWidth" format="dimension"/>
  <attr name="borderLeftMargin" format="dimension"/>
  <attr name="borderLeftMarginStart" format="dimension"/>
  <attr name="borderLeftMarginEnd" format="dimension"/>

  <!--上边线的drawable,颜色,宽度,和边线padding-->
  <attr name="borderTop" format="reference"/>
  <attr name="borderTopColor" format="color"/>
  <attr name="borderTopWidth" format="dimension"/>
  <attr name="borderTopMargin" format="dimension"/>
  <attr name="borderTopMarginStart" format="dimension"/>
  <attr name="borderTopMarginEnd" format="dimension"/>

  <!--右边线drawable,颜色,宽度,和边线padding-->
  <attr name="borderRight" format="reference"/>
  <attr name="borderRightColor" format="color"/>
  <attr name="borderRightWidth" format="dimension"/>
  <attr name="borderRightMargin" format="dimension"/>
  <attr name="borderRightMarginStart" format="dimension"/>
  <attr name="borderRightMarginEnd" format="dimension"/>

  <!--下边线的drawable,颜色,宽度,和边线padding-->
  <attr name="borderBottom" format="reference"/>
  <attr name="borderBottomColor" format="color"/>
  <attr name="borderBottomWidth" format="dimension"/>
  <attr name="borderBottomMargin" format="dimension"/>
  <attr name="borderBottomMarginStart" format="dimension"/>
  <attr name="borderBottomMarginEnd" format="dimension"/>

  <!--内容四边的间距,不同于padding -->
  <attr name="contentMargin" format="dimension" />
  <attr name="contentMarginHorizontal" format="dimension" />
  <attr name="contentMarginVertical" format="dimension" />
  <attr name="contentMarginLeft" format="dimension"/>
  <attr name="contentMarginTop" format="dimension"/>
  <attr name="contentMarginRight" format="dimension"/>
  <attr name="contentMarginBottom" format="dimension"/>
  
  <!--水平方向和垂直方向Item 的间距-->
  <attr name="itemMargin" format="dimension"/>
  <attr name="itemMarginHorizontal" format="dimension"/>
  <attr name="itemMarginVertical" format="dimension"/>

  <!--水平分割线drawable-->
  <attr name="dividerHorizontal" format="reference" />
  <!--水平分割线颜色-->
  <attr name="dividerColorHorizontal" format="color"/>
  <!--水平分割线宽-->
  <attr name="dividerWidthHorizontal" format="dimension"/>
  <!--水平分割线开始和结束padding-->
  <attr name="dividerPaddingHorizontal" format="dimension"/>
  <attr name="dividerPaddingHorizontalStart" format="dimension"/>
  <attr name="dividerPaddingHorizontalEnd" format="dimension"/>


  <!--垂直分割线drawable-->
  <attr name="dividerVertical" format="reference" />
  <!--垂直分割线颜色-->
  <attr name="dividerColorVertical" format="color"/>
  <!--垂直分割线宽-->
  <attr name="dividerWidthVertical" format="dimension"/>
  <!--垂直分割线开始 和结束padding-->
  <attr name="dividerPaddingVertical" format="dimension"/>
  <attr name="dividerPaddingVerticalStart" format="dimension"/>
  <attr name="dividerPaddingVerticalEnd" format="dimension"/>

具体容器组件的属性和使用介绍

1.ColumnLayout xml 属性支持属性如下:java 都有对应的set和get方法就不给示例了,内容分割线间距见以上通用属性。

  <!--列个数-->
  <attr name="columnNumber" format="integer" />
  <!--每行内容垂直居中-->
  <attr name="columnCenterVertical" format="boolean"/>

  <!--列内内容全展开的索引 * 或 1,3,5 类似列索引0 开始-->
  <attr name="stretchColumns" format="string" />
  <!--列内内容全靠中间 * 或 1,3,5 类似列索引0 开始-->
  <attr name="alignCenterColumns" format="string" />
  <!--列内内容全靠右 * 或 1,3,5 类似列索引0 开始-->
  <attr name="alignRightColumns" format="string" />

  <!--列宽和高的最大最小值限定-->
  <attr name="columnMinWidth" format="dimension" />
  <attr name="columnMaxWidth" format="dimension" />
  <attr name="columnMinHeight" format="dimension" />
  <attr name="columnMaxHeight" format="dimension" />

2.NestRefreshLayout 在xml 中可像ScrollView一样用,只支持一个内容。可动态设置头部和尾部。

   //可选,设置头部headerView,true 表示悬停在内容上。
   refreshLayout.setHeaderView(headerView, true);
   
   //可选,设置尾部footerView,false 表示不需要悬停在内容上。
   refreshLayout.setFooterView(footerView, false);
   
   //可选,设置覆盖内容的蒙层 View。
   refreshLayout.setMaskView(maskView, true);
   
   //设置下拉刷新的指示器。
   refreshLayout.setRefreshPullIndicator(new DefaultRefreshIndicator(getActivity()));
   //设置上拉加载更多的指示器。
   refreshLayout.setRefreshPushIndicator(new DefaultRefreshIndicator(getActivity()));
   
   设置下拉或上推的状态和刷新动作的监听
   mRefreshLayout.setOnRefreshListener(new NestRefreshLayout.OnRefreshListener() {
      @Override
      public void onRefreshStateChanged(NestRefreshLayout parent, int state, int preState, int moveAbsDistance) {
      }
      @Override
      public void onRefresh(NestRefreshLayout parent, boolean refresh) {
      }
   });

3.NestFloatLayou xml 属性支持属性和 java 代码如下:

 <!--实现了嵌套滑动NestScrollingChild 接口的滑动的 View 所在的直接子 View 索引-->
 <attr name="nestViewIndex" format="integer"/>```
 <!--需要吸顶到顶部的 View 所在的直接子 View 索引-->
 <attr name="floatViewIndex" format="integer"/>`java`代码可如下设置:
 mLastFloatLayout.setNestViewId(viewId);
 mLastFloatLayout.setFloatViewId(viewId);
 
  mLastFloatLayout.setNestViewIndex(viewIndex);
  mLastFloatLayout.setFloatViewIndex(viewIndex);

4.PageScrollView,PageScrollTab 使用.

a. 支持的xml 属性,对应都有java 相应的set 和 get;

  <!--布局方向,也决定了手势方向,仅支持水平和垂直之一。-->
  <attr name="layoutDirection"/>
  <!--滑动交互 ViewPager 方式-->
  <attr name="viewPagerStyle" format="boolean"/>
  <!--所有的child居中-->
  <attr name="childCenter" format="boolean"/>
  <!--所有的child填充整个父容器-->
  <attr name="childFillParent" format="boolean"/>
  <!--内容item 的间距-->
  <attr name="middleMargin" format="dimension"/>
  <!--item 的size 按父容器的size 百分比-->
  <attr name="sizeFixedPercent" format="float"/>
  <!--快速滑动松手后的回弹距离-->
  <attr name="overFlingDistance" format="dimension"/>
  <!--滑动悬停到开始位置的child 索引-->
  <attr name="floatViewStartIndex" format="integer"/>
  <!--滑动悬停到结束位置的child 索引-->
  <attr name="floatViewEndIndex" format="integer"/>

b.java 其它接口设置

//接着上面
  mPageScrollView.setPageHeadView(headerView); //设置头部 View
  mPageScrollView.setPageFooterView(footerView); 设置尾部 View
  //设置 PageTransformer 动画,实现滑动视图的变换。
  mPageScrollView.setPageTransformer(new PageScrollView.PageTransformer() {
  @Override
  public void transformPage(View view, float position, boolean horizontal) {
  //在这里根据滑动相对偏移量 position,实现该视图的动画效果。
  }
  @Override
  public void recoverTransformPage(View view, boolean horizontal) {
  //清除视图的动画效果,在setPageTransformer(null)时会调用。
  }
  });
  PageScrollView.OnPageChangeListener pagerScrollListener = new PageScrollView.OnPageChangeListener() {
  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  // ViewPager 滑动视图时,相对偏移适时回调。
  }
  @Override
  public void onPageSelected(int position, int oldPosition) {
  // ViewPager 模式时 选中回调。
  }
  @Override
  public void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
  //视图滑动回调 View.onScrollChanged
  }
  @Override
  public void onScrollStateChanged(int state, int oldState) {
  //state 的取值如下,标明着容器的滑动状态。
  // SCROLL_STATE_IDLE = 0; // 滑动停止状态。
  // SCROLL_STATE_DRAGGING = 1;//用户正开始拖拽滑动 。
  // SCROLL_STATE_SETTLING = 2;//开始松开手指快速滑动。
  }
  };
  mPageScrollView.setOnPageChangeListener(pagerScrollListener);
  // 设置视图滚动的监听。
  mPageScrollView.setOnScrollChangeListener(pagerScrollListener);
  //设置可见子 View 发生变化时 可见索引区间的监听。
  mPageScrollView.setOnVisibleRangeChangeListener(new OnVisibleRangeChangeListener(){
      public void onVisibleRangeChanged(int firstVisible, int lastVisible, int oldFirstVisible, int oldLastVisible){
      }
  });
  //设置动画初始化滑动到第二个 View ,-1 表示动画时间内部计算,如无需动画传0
  mPageScrollView.scrollTo(1,0,-1);

c.PageScrollTab 继承于 PageScrollView ,额外支持以下xml 属性(java 均有get 和set 对应)。

 <!--tab item 的背景-->
   <attr name="tabItemBackground" format="reference"/>
   <attr name="tabItemBackgroundFirst" format="reference"/>
   <attr name="tabItemBackgroundLast" format="reference"/>
   <attr name="tabItemBackgroundFull" format="reference"/>

   <!--底部指示线-->
   <attr name="tabIndicatorColor" format="color"/>
   <attr name="tabIndicatorHeight" format="dimension"/>
   <attr name="tabIndicatorOffset" format="dimension"/>
   <attr name="tabIndicatorWidthPercent" format="float"/>

   <!--顶部水平分界线-->
   <attr name="tabTopLineColor" format="color"/>
   <attr name="tabTopLineHeight" format="dimension"/>

   <!--底部水平分界线-->
   <attr name="tabBottomLineColor" format="color"/>
   <attr name="tabBottomLineHeight" format="dimension"/>

   <!-- item 之间垂直分割线-->
   <attr name="tabItemDividerColor" format="color"/>
   <attr name="tabItemDividerWidth" format="dimension"/>
   <attr name="tabItemDividerPadding" format="dimension"/>


   <!-- item 的最小 Padding 设置-->
   <attr name="tabItemMinPaddingHorizontal" format="dimension"/>
   <attr name="tabItemMinPaddingTop" format="dimension"/>
   <attr name="tabItemMinPaddingBottom" format="dimension"/>

   <!--item文字大写开-->
   <attr name="tabItemTextCaps" format="boolean"/>

   <!--item 文字颜色-->
   <attr name="tabItemTextColor" format="reference"/>

java 额外的接口:

  //设置ItemProvider,初始化选中第0 个索引, 类似上面的 LabelLayout 的初始化。
  mPageScrollTab.setTabProvider(mItemProvider,0);
  mPageScrollTab.setTabClickListener(new PageScrollTab.ITabClickEvent() {
      @Override
      public boolean onTabClicked(PageScrollTab parent, View cur, int curPos, View pre, int prePos) {
          return false;
      }
  });

5.WrapLayout xml 属性支持属性如下:java 都有对应的set 和get 方法就不给示例了。当作LinearLayout如果要支持weight布局,需要设置 setSupportWeight为true见weightSupport. 且垂直布局需设置lineMaxItemCount为1,水平布局时lineMinItemCount可不设,也可设置为一个大于或等于子视图数的值或设置小于1 的值. 只有这样才可以应用权重去做垂直或是水平的布局。

  <!--每行内容水平居中-->
  <attr name="lineCenterHorizontal" format="boolean"/>
  <!--每行内容垂直居中-->
  <attr name="lineCenterVertical" format="boolean"/>

  <!--每一行最少的Item 个数-->
  <attr name="lineMinItemCount" format="integer"/>
  <!--每一行最多的Item 个数-->
  <attr name="lineMaxItemCount" format="integer"/>
  
  <!-- 支持weight 属性,前提条件是单行或单列的情况-->
  <attr name="weightSupport" format="boolean" />

6.LabelLayout 继承WrapLayout有其所有功能接口。

不同是支持 android:textSize,android:textColor 在xml 中设置Label 的字号和字色。同样可用java 代码设置字号字色。 使用可通过ItemProvider 接口来初始化 Label,本工程中的示例初始化如下。

final String[] mLabels = new String[]{
        "A", "B", "C", "D", "E", "F", "G", "H"
};
labelLayout.setItemProvider(new ItemProvider.ViewProvider() {
    @Override
    public int getViewType(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return buildView(getTitle(position),true);
    }

    @Override
    public CharSequence getTitle(int position) {
        return mLabels[position];
    }

    @Override
    public Object getItem(int position) {
        return mLabels[position];
    }

    @Override
    public int getCount() {
        return mLabels == null ? 0 : mLabels.length;
    }
});
final LabelLayout.OnLabelClickListener mLabelClicker = new LabelLayout.OnLabelClickListener() {
    @Override
    public void onLabelClick(LabelLayout parent, View labelView) {
        Object tag = labelView.getTag();
        CharSequence text = tag == null ? null : String.valueOf(tag);
        if (text == null && labelView instanceof TextView) {
            text = ((TextView) labelView).getText();
        }
        if (text != null) {
            Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show();
        }
    }
};
mLabelLayout.setOnLabelClickListener(mLabelClicker);

最后感谢大家关注和多提建议或是issue,如果很感兴趣请 star 和 follower .

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].