yhyzgn / Widgets

封装了一些常用的自定义View,用于快捷开发

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Widgets

996.icu LICENSE

widget是一个Android自定义控件库。包含多种常用控件。

☆ 注意 ☆

1.4.1开始,全面支持AndroidX,弃用support

效果展示

控件展示较多,更新也较频繁,不方便录制gif图片,请下载demo体验。

基本使用

  • 引入jitpack

    仓库已迁移到jitpack

    allprojects {
        repositories {
            // ...
            maven { url "https://jitpack.io" }
        }
    }
  • 添加依赖

    在项目主模块中添加如下依赖

    dependencies {
        implementation 'com.github.yhyzgn:Widgets:latestVersion'
    }

控件总览

简要罗列各种控件

使用说明

core控件

  • PreImgActivity

    点击查看大图功能

    • Application中初始化

      需要在Application中初始化,并通过ImgPreHelper设置图片加载器、图片下载器等相关配置

      ImgPreHelper.getInstance().init(this).setLoader(new ImgPreHelper.ImgLoader() {
          @Override
          public <T> void load(ImageView iv, T model, ProgressBar pbLoading) {
              Glide.with(iv.getContext()).load(model).into(iv);
          }
      }).setOnDownloadListener(new ImgPreHelper.OnDownloadListener() {
          @Override
          public void onProgress(float progress, long current, long total) {
              Log.i("ImgDownloader", "下载进度:" + (progress * 100F) + "%,总大小:" + total + " bytes, 已下载:" + current + " bytes.");
          }
      
          @Override
          public void onSuccess(File img, String msg) {
              ToastUtils.shortT(msg);
          }
      
          @Override
          public void onError(String error) {
              ToastUtils.shortT(error);
          }
      });
    • 设置ImgPreCfg参数

      多张图

      // 多张图
      List<String> urlList = new ArrayList<>();
      urlList.add("http://img.youguoquan.com/uploads/magazine/content/a811c176420a20f8e035fc3679f19a10_magazine_web_m.jpg");
      urlList.add("http://img.youguoquan.com/uploads/magazine/content/7b2a0fdbb23c9e63586b7ff6798dbebb_magazine_web_m.jpg");
      urlList.add("http://img.youguoquan.com/uploads/magazine/content/c9c47160b46fceab5afd24dea7f216e6_magazine_web_m.jpg");
      urlList.add("http://img.youguoquan.com/uploads/magazine/content/fd986a6e0d5fa3a4485e5ce28f40b2ad_magazine_web_m.jpg");
      // 参数1为点击的ImageView;参数3为当前要预览的图片索引。
      ImgPreCfg cfg = new ImgPreCfg(iv, urlList, 1);

      一张图

      // 参数1为点击的ImageView;参数2为当前要预览的图片地址。
      ImgPreCfg cfg = new ImgPreCfg(iv, url);
      
      // 配置为不可下载
      cfg.setDownloadable(false);
      // 设置下载按钮图标
      cfg.setDownloadIconId(R.mipmap.ic_def_download);
      
      // x, y, width, height 分别为图片x, y坐标和宽高度。
      ImgPreCfg cfg = new ImgPreCfg(x, y, width, height, url);
    • 开始预览

      PreImgActivity.preview(this, cfg);
  • AdvView

    广告轮播展示栏

    • 布局文件

      <com.yhy.widget.core.adv.AdvView
        android:id="@+id/av_view_multiple"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:background="#ac0"
        app:av_anim_duration="1000"
        app:av_interval="4000" />
    • 获取控件

      AdvView avMultiple = findViewById(R.id.av_view_multiple);
    • 设置数据和事件

      设置数据

      List<String> mItems = new ArrayList<>();
      mItems.add("这是第1个");
      mItems.add("这是第2个");
      mItems.add("这是很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的第3个");
      mItems.add("这是第4个");
      mItems.add("这是第5个");
      mItems.add("这是第6个");
      mItems.add("这是第7个");
      
      // 第3个参数为每页展示广告条数,默认为1,即单条展示
      SimpleAdvAdapter<String> avAdapter = new SimpleAdvAdapter<String>(this, mItems, 3) {
        @Override
        protected View getItemView(int position, String data) {
          TextView tv = new TextView(mCtx);
          tv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
          tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
          tv.setText(data);
          tv.setTextColor(Color.DKGRAY);
          tv.setTextSize(14);
          tv.setSingleLine();
          tv.setEllipsize(TextUtils.TruncateAt.END);
          return tv;
        }
      };
      
      // 设置适配器到AdvView
      avMultiple.setAdapter(avAdapter);

      设置条目点击事件

      avAdapter.setOnItemClickListener(new SimpleAdvAdapter.OnItemClickListener<String>() {
        @Override
        public void onItemClick(SimpleAdvAdapter adapter, int position, String data) {
          toast("position = " + position + ", " + data);
        }
      });
    • 自定义属性

      属性 说明 默认值
      av_interval 动画定时,单位ms 3000
      av_anim_duration 动画执行时间,单位ms 800
      av_anim_in 入场动画资源 R.anim.adv_in
      av_anim_out 出场动画资源 R.anim.adv_out
  • CheckedTextView

    可选中的TextView

    • 布局文件

      背景选择器bg_checked_ctv_selector

      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_checked="true">
          <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent" />
            <corners android:radius="4dp" />
          </shape>
        </item>
        <item>
          <shape android:shape="rectangle">
            <solid android:color="#666" />
            <corners android:radius="4dp" />
          </shape>
        </item>
      </selector>

      布局

      <com.yhy.widget.core.checked.CheckedTextView
        android:id="@+id/ctv_def"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_checked_ctv_selector"
        android:padding="8dp"
        android:text="阻止了Click和LongClick事件"
        android:textColor="#fff"
        android:textSize="14sp" />
        <!-- 默认阻止了click和longClick事件,如果需要添加这些事件,请添加属性:app:ctv_prevent="false" -->
    • 获取控件

      CheckedTextView ctvDef = findViewById(R.id.ctv_def);
    • 设置事件

      ctvDef.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          toast("我的click被阻止了");
        }
      });
      
      ctvDef.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
          toast("我的longClick被阻止了");
          return true;
        }
      });
      
      ctvDef.setOnCheckedChangeListener(new CheckedTextView.OnCheckedChangeListener() {
        @Override
        public void onChanged(CheckedTextView ctv, boolean isChecked) {
          toast("isChecked = " + isChecked);
        }
      });
    • 自定义属性

      属性 说明 默认值
      ctv_prevent 是否阻止clicklongClick事件 true
  • ExpandTextView

    可展开收起的TextView

    • 布局文件

      <com.yhy.widget.core.exptext.ExpandTextView
        android:id="@+id/etv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        android:orientation="vertical"
        app:etv_anim_alpha_start="0.2"
        app:etv_anim_duration="800"
        app:etv_max_collapsed_lines="4">
      
        <!-- 显示文本内容的TextView -->
        <TextView
          android:id="@+id/tv_content"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_marginLeft="10dp"
          android:layout_marginRight="10dp"
          android:layout_marginTop="8dp"
          android:ellipsize="end"
          android:textColor="#666666"
          android:textSize="16sp"/>
      
        <!--展开和收起的点击按钮-->
        <TextView
          android:id="@+id/tv_expand"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_gravity="end|bottom"
          android:padding="16dp"
          android:text="窝草"/>
      </com.yhy.widget.core.exptext.ExpandTextView>
    • 获取控件

      ExpandTextView etvContent = findViewById(R.id.etv_content);
      // 配置内容控件和按钮控件
      etvContent.mapViewId(R.id.tv_content, R.id.tv_expand);
    • 设置数据

      etvContent.setText("哈哈哈哈哈哈啊哈哈哈哈");
    • 设置事件

      etvContent.setOnExpandStateChangeListener(new ExpandTextView.OnExpandStateChangeListener() {
        @Override
        public void onExpandStateChanged(TextView textView, boolean isExpanded) {
          toast(isExpanded ? "展开了" : "收起了");
        }
      });
    • 自定义属性

      属性 说明 默认值
      etv_max_collapsed_lines 收缩时显示的最大行数 2
      etv_anim_duration 动画执行时间,单位ms 400m
      etv_anim_alpha_start 透明度动画开始时的值 0.6
  • SquareImageView

    正方形ImageView

    • 布局文件

      <com.yhy.widget.core.img.SquareImageView 
        android:id="@+id/siv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:siv_btn_img="@drawable/ic_delete_white" />
    • 获取控件

      SquareImageView sivTest = findViewById(R.id.siv_test);
    • 设置数据

      Glide.with(ctx).load(url).into(sivTest);
    • 设置事件

      sivTest.setOnBtnClickListener(new SquareImageView.OnBtnClickListener() {
        @Override
        public void onClick(SquareImageView siv) {
          Toast.makeText(SquareIVActivity.this, "删除第" + position + "张图片", Toast.LENGTH_SHORT).show();
        }
      });
    • 自定义属性

      属性 说明 默认值
      siv_btn_img 右上角按钮图片
      siv_btn_size 右上角按钮大小,单位dp 0
      siv_btn_padding 右上角按钮内边距,单位dp 2
  • CircleImageView

    圆形图片

    • 布局文件

      <com.yhy.widget.core.img.round.CircleImageView
        android:id="@+id/civ_avatar"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        app:riv_border_color="#8c9eff"
        app:riv_border_width="2dp" />
    • 获取控件

      CircleImageView civTest = findViewById(R.id.civ_test);
    • 设置数据

      Glide.with(ctx).load(url).into(civTest);
    • 自定义属性

      属性 说明 默认值
      riv_border_width 边框宽度,单位dp 0
      riv_border_color 边框颜色 #000000
  • RoundImageView

    圆角图片,如果四个角半径都相等的话,直接使用riv_radius即可

    • 布局文件

      <com.yhy.widget.core.img.round.RoundImageView
        android:id="@+id/riv_d"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginLeft="10dp"
        android:scaleType="centerCrop"
        app:riv_border_color="#8c9eff"
        app:riv_border_width="2dp"
        app:riv_radius_left_top="30dp"
        app:riv_radius_right_top="30dp"
        app:riv_radius_right_bottom="30dp"
        app:riv_radius_left_bottom="30dp"
        app:riv_radius="12dp" />
    • 获取控件

      CircleImageView rivTest = findViewById(R.id.riv_test);
    • 设置数据

      Glide.with(ctx).load(url).into(rivTest);
    • 自定义属性

      属性 说明 默认值
      civ_border_width 边框宽度,单位dp 0
      civ_border_color 边框颜色 #000000
      riv_radius 圆角半径,单位dp 0
      riv_radius_left_top 左上角圆角半径 riv_radius
      riv_radius_right_top 右上角圆角半径 riv_radius
      riv_radius_right_bottom 右下角圆角半径 riv_radius
      riv_radius_left_bottom 左下角圆角半径 riv_radius
  • HackyViewPager

    多点触摸滑动时防止内存溢出的ViewPager

    当成普通ViewPager使用即可

  • PickerView

    上下滚动数据选取控件

    • 布局文件

      <com.yhy.widget.core.picker.PickerView
        android:id="@+id/pv_test"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:pv_text_color="#f20"/>
    • 获取控件

      // // 泛型表示该控件中数据源的数据类型
      PickerView<TestEntity> pvText = findViewById(R.id.pv_test);
    • 设置数据及事件

      List<TestEntity> testList = new ArrayList<>();
      for (int i = 1; i <= 40; i++) {
        testList.add(new TestEntity(i, "Data " + i));
      }
      
      pvTest.setData(testList, new PickerView.ItemProvider<TestEntity>() {
        @Override
        public String getItem(TestEntity data, int position) {
          return data.name;
        }
      }).setOnSelectListener(new PickerView.OnSelectListener<TestEntity>() {
        @Override
        public void onSelect(TestEntity data) {
          toast(data.name);
        }
      });
    • 自定义属性

      属性 说明 默认值
      pv_max_text_size 字体最大尺寸,单位dp 20
      pv_min_text_size 字体最小尺寸,单位dp 14
      pv_text_color 字体颜色 #e84c3d
  • RecyclerScrollView

    用来嵌套RecyclerViewScrollView

    当成普通ScrollView使用即可

    • 设置滚动监听事件

      rsvTest.setOnScrollListener(new OnScrollListener() {
        @Override
        public void onScroll(RecyclerScrollView view, int x, int y, int oldX, int oldY){
          toast("当前滚动条y坐标为:" + y);
        }
      });
  • RvDivider

    RecyclerView的分割线

    目前只针对LinearLayoutManagerGridLayoutManager两种布局

    注意:一定要在设置适配器后添加分割线

    • 创建分割线

      RvDivider mDivider = new RvDivider.Builder(this)
        .widthDp(30)
        .color(getResources().getColor(R.color.colorPrimary))
        .type(RvDivider.DividerType.TYPE_WITH_START_END)
        .build();
    • LinearLayoutManager

      rvContent.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
      // 先设置适配器,再添加分割线
      rvContent.addItemDecoration(mDivider);
    • GridLayoutManager

      rvContent.setLayoutManager(new GridLayoutManager(this, 4));
      // 先设置适配器,再添加分割线
      rvContent.addItemDecoration(mDivider);
  • SettingsItemView

    常用设置布局中的条目控件

    • 布局文件

      <com.yhy.widget.core.settings.SettingsItemView
        android:id="@+id/siv_test"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="#fff"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        app:siv_name="设置1"
        app:siv_text="值1" />
    • 获取控件

      SettingsItemView sivTest = findViewById(R.id.siv_test);
    • 设置数据

      sivTest.setName("左边文字").setText("右边文字");
      // ... 还有设置图标之类的各种方法,如下
      sivTest.setIcon(mIcon)
        .showIcon(mShowIcon)
        .setArrow(mArrow)
        .showArrow(mShowArrow)
        .setName(mName)
        .setNameWidth(mNameWidth)
        .setNameColor(mNameColor)
        .setNameSize(mNameSize)
        .setText(mText)
        .setHint(mHint)
        .setEditable(mEditable)
        .setTextColor(mTextColor)
        .setTextSize(mTextSize)
        .onSwitch(mSwitchOn)
        .showSwitch(mShowSwitch)
        .setNameGravity(mNameGravity)
        .setTextGravity(mTextGravity)
        .setCursorDrawableRes(mCursorDrawableRes);
      
      // 如果有开关控件,还需要设置开关监听事件
      sivTest.setOnSwitchStateChangeListener(new SettingsItemView.OnSwitchStateChangeListener() {
        @Override
        public void onStateChanged(SettingsItemView siv, SwitchButton sb, boolean isOn) {
          toast(siv.getName() + " :: isOn = " + isOn);
        }
      });
    • 自定义属性

      属性 说明 默认值
      siv_icon 左边图标
      siv_show_icon 是否显示左边图标 false
      siv_arrow 右边箭头
      siv_show_arrow 是否显示右边箭头 false
      siv_name 左边文本
      siv_name_width 左边文本宽度,单位dp 自适应
      siv_name_gravity 左边文本对其方式【leftcenterright center
      siv_name_size 左边文本大小,单位sp 14
      siv_name_color 左边文本颜色 #000000
      siv_text 右边内容
      siv_text_gravity 右边内容对齐方式【leftcenterright center
      siv_hint 右边提示文本
      siv_text_size 右边字体大小,单位sp 14
      siv_text_color 右边字体颜色 #000000
      siv_switch_on 是否打开开关 false
      siv_switch_width 开关控件宽度,单位dp 48
      siv_switch_height 开关控件高度,单位dp 28
      siv_show_switch 是否显示开关控件 false
      siv_editable 是否可编辑 false
      siv_cursor_drawable 光标颜色资源 系统默认
      siv_input_type 输入类型【textphoneemailpassword text
      siv_max_length 可输入最大长度 不限
  • TitleBar

    常用标题栏控件

    • 布局文件

      <com.yhy.widget.core.title.TitleBar
        android:id="@+id/tb_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#7ad"
        android:elevation="8dp"
        app:tb_title="测试标题" />
    • 获取控件

      TitleBar tbTest = findViewById(R.id.tb_test);
    • 设置数据及事件

      tbTest.setTitle("标题");
      
      // ******** 该方法已过时 ********
      // 事件,该监听器不是接口或者抽象类,只需要重写对应的方法即可
      tbTest2.setOnTitleBarListener(new TitleBar.OnTitleBarListener() {
          @Override
          public void titleClick(View view) {
              toast("点击了标题");
          }
      
          @Override
          public void leftIconClick(View view) {
              toast("返回");
              finish();
          }
      
          @Override
          public void leftTextClick(View view) {
              toast("左边文本");
          }
      
          @Override
          public void rightIconClick(View view) {
              toast("右边图标");
          }
      
          @Override
          public void rightTextClick(View view) {
              toast("右边文本");
          }
      });
      
      // 以上方法已过时,用一下方法代替
      // 点击事件
      tbTest2.setOnTitleBarClickListener(new TitleBar.OnTitleBarClickListener() {
          @Override
          public void titleClick(View view) {
              toast("点击了标题");
          }
      
          @Override
          public void leftIconClick(View view) {
              toast("返回");
              finish();
          }
      
          @Override
          public void leftTextClick(View view) {
              toast("左边文本");
          }
      
          @Override
          public void rightIconClick(View view) {
              toast("右边图标");
          }
      
          @Override
          public void rightTextClick(View view) {
              toast("右边文本");
          }
      });
      
      // 长按事件【是否在长按后再加一个短按动作(true为不加短按,false为加入短按)】
      tbTest2.setOnTitleBarLongClickListener(new TitleBar.OnTitleBarLongClickListener {
          public boolean titleLongClick(View view) {
              return false;
          }
      
          public boolean leftTextLongClick(View view) {
              return false;
          }
      
          public boolean rightTextLongClick(View view) {
              return false;
          }
      
          public boolean leftIconLongClick(View view) {
              return false;
          }
      
          public boolean rightIconLongClick(View view) {
              return false;
          }
      });
    • 自定义属性

      属性 说明 默认值
      tb_title 标题文本
      tb_left_text 左边文本
      tb_right_text 右边文本
      tb_left_icon 左边图标
      tb_right_icon 右边图标
      tb_font_color 全部字体颜色 #ffffff
      tb_title_color 标题字体颜色 #ffffff
      tb_left_text_color 左边字体颜色 #ffffff
      tb_right_text_color 右边字体颜色 #ffffff
      tb_title_size 标题字体大小,单位sp 18
      tb_left_text_size 左边字体大小,单位sp 14
      tb_right_text_size 右边字体大小,单位sp 14
  • SwitchButton

    常用开关控件

    • 布局文件

      <com.yhy.widget.core.toggle.SwitchButton
        android:id="@+id/switch_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"/>
    • 获取控件

      SwitchButton switchButton = findViewById(R.id.switch_button);
    • 设置数据事件

      switchButton.onOrOff(true);
      switchButton.isOn();
      switchButton.toggle();     //switch state
      switchButton.toggle(false);//switch without animation
      switchButton.setShadowEffect(true);//disable shadow effect
      switchButton.setEnabled(true);//disable button
      switchButton.setEnableEffect(false);//disable the switch animation
      
      switchButton.setOnStateChangeListener(new SwitchButton.OnStateChangeListener() {
        @Override
        public void onCheckedChanged(SwitchButton view, boolean isOn) {
          toast("isOn = " + isOn);
        }
      });
    • 自定义属性

      属性 说明 默认值
      sb_shadow_radius 阴影半径,单位dp 2.5
      sb_shadow_offset 阴影偏移值,单位dp 1.5
      sb_shadow_color 阴影颜色 #33000000
      sb_off_color 关闭时颜色 #dddddd
      sb_on_color 打开时颜色 #51d367
      sb_border_width 边框宽度,单位dp 1
      sb_on_line_color 打开状态中短竖线颜色 #ffffff
      sb_on_line_width 打开状态中短竖线宽度,单位dp 1
      sb_off_circle_color 关闭状态中圆圈颜色 #aaaaaa
      sb_off_circle_width 关闭状态中圆圈宽度,单位dp 1.5
      sb_off_circle_radius 关闭状态中圆圈半径,单位dp 4
      sb_on 是否打开 false
      sb_shadow_effect 是否支持阴影效果 true
      sb_effect_duration 效果显示时间,单位ms 300
      sb_button_color 按钮颜色 #ffffff
      sb_show_indicator 是否显示指示器 true
      sb_background 背景颜色 #ffffff
      sb_enable_effect 是否开启特效 true
  • StepView

    可步骤化控件,包括垂直方向和水平方向

    • 布局文件

      <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scrollbars="none">
      
        <com.yhy.widget.core.step.StepView
          android:id="@+id/sv_vertical"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:sv_complete_icon="@mipmap/ic_step_finished" />
      </ScrollView>
    • 获取控件

      StepView<TestStep> svVertical = $(R.id.sv_vertical);
    • 设置数据事件

      模拟数据

      private final List<TestStep> mStepVerticalList = new ArrayList<>();
      
      // ...
      
      mStepVerticalList.clear();
      mStepVerticalList.add(new TestStep("您已提交定单,等待系统确认"));
      mStepVerticalList.add(new TestStep("您的商品需要从外地调拨,我们会尽快处理,请耐心等待"));
      mStepVerticalList.add(new TestStep("您的订单已经进入亚洲第一仓储中心1号库准备出库"));
      mStepVerticalList.add(new TestStep("您的订单预计6月23日送达您的手中,618期间促销火爆,可能影响送货时间,请您谅解,我们会第一时间送到您的手中"));
      mStepVerticalList.add(new TestStep("您的订单已打印完毕"));
      mStepVerticalList.add(new TestStep("您的订单已拣货完成"));
      mStepVerticalList.add(new TestStep("扫描员已经扫描"));
      mStepVerticalList.add(new TestStep("打包成功"));
      mStepVerticalList.add(new TestStep("您的订单在京东【华东外单分拣中心】发货完成,准备送往京东【北京通州分拣中心】"));
      mStepVerticalList.add(new TestStep("您的订单在京东【北京通州分拣中心】分拣完成"));
      mStepVerticalList.add(new TestStep("您的订单在京东【北京通州分拣中心】发货完成,准备送往京东【北京中关村大厦站】"));
      mStepVerticalList.add(new TestStep("您的订单在京东【北京中关村大厦站】验货完成,正在分配配送员"));
      // 当前状态
      mStepVerticalList.add(new TestStep("配送员【哈哈哈】已出发,联系电话【130-0000-0000】,感谢您的耐心等待,参加评价还能赢取好多礼物哦", StepAble.Status.CURRENT));
      // 默认状态
      mStepVerticalList.add(new TestStep("感谢你在京东购物,欢迎你下次光临!", StepAble.Status.DEFAULT));
      
      // 反转数据
      Collections.reverse(mStepVerticalList);

      设置适配器

      private class VerticalAdapter extends StepAdapter<TestStep> {
          public VerticalAdapter() {
              super(mStepVerticalList);
          }
      
          @Override
          public View getItem(StepView<TestStep> stepView, int position, TestStep data) {
              View view = LayoutInflater.from(StepActivity.this).inflate(R.layout.item_step_vertical, null);
              TextView tvTest = view.findViewById(R.id.tv_test);
              tvTest.setText(data.text);
              if (data.getStatus() == StepAble.Status.COMPLETE) {
                  tvTest.setTextColor(Color.parseColor("#00beaf"));
              } else if (data.getStatus() == StepAble.Status.CURRENT) {
                  tvTest.setTextColor(Color.parseColor("#ff7500"));
              } else {
                  tvTest.setTextColor(Color.parseColor("#dcdcdc"));
              }
              return view;
          }
      }
      
      // 设置适配器
      mVerticalAdapter = new VerticalAdapter();
      svVertical.setAdapter(mVerticalAdapter);

      设置条目点击事件

      svVertical.setOnItemClickListener(new StepView.OnItemClickListener<TestStep>() {
          @Override
          public void onItemClick(StepView<TestStep> parent, int position, TestStep data) {
              toast(data.text);
          }
      });
    • 自定义属性

      属性 说明 默认值
      sv_orientation 显示方向【verticalhorizontal vertical
      sv_complete_color 完成状态节点圆的颜色 #00beaf
      sv_current_color 当前状态节点圆的颜色 #ff7500
      sv_default_color 默认状态节点圆的颜色 #dcdcdc
      sv_solid_line_color 实线颜色 #00beaf
      sv_solid_line_width 实线宽度 2dp
      sv_dash_line_color 虚线颜色 #00beaf
      sv_dash_line_width 虚线宽度 1dp
      sv_radius 节点圆的半径 8dp
      sv_complete_icon 完成状态节点的图标
      sv_current_icon 当前状态节点的图标
      sv_default_icon 默认状态节点的图标
      sv_align_middle 是否将节点圆与itemView的中间位置对齐,不对齐则对齐itemView的左边或者上边 true
  • HybridBridge

    加强版的WebView,可以直接和js交互

    这里只是Android端说明,Web端说明请参考hybrid

    • 布局文件

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
      
        <com.yhy.widget.core.web.HybridWebView
          android:id="@+id/hwv_content"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
      
        <Button
          android:id="@+id/btn_test"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true"
          android:layout_centerHorizontal="true"
          android:layout_marginBottom="32dp"
          android:text="点击试试" />
      </RelativeLayout>
    • 获取控件

      HybridWebView hwvContent = $(R.id.hwv_content);
      Button btnTest = $(R.id.btn_test);
    • 设置数据

      // 注册交互桥梁
      hwvContent.register(new TestBridge());
      // 加载页面
      hwvContent.loadUrl("file:///android_asset/index.html");
      
      // ...
      
      /**
       * 交互桥梁,必须是HybridBridge的子类
       */
      public class TestBridge extends HybridBridge {
      
          @JavascriptInterface
          public String test(String json) {
              Toast.makeText(WebHybridActivity.this, json, Toast.LENGTH_LONG).show();
              return "Android接收到数据啦";
          }
      }
    • 设置事件

      hwvContent.setOnWebEventListener(new SimpleOnWebEventListener() {
          @Override
          public boolean onJsAlert(HybridWebView view, String url, String message, final JsResult result) {
              AlertDialog.Builder builder = new AlertDialog.Builder(WebHybridActivity.this);
              builder
                  .setTitle("标题")
                  .setMessage(message)
                  .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          result.confirm();
                      }
                  })
                  .show();
              //返回true表示不再往下传递弹窗事件,即不再使用原本WebView的弹窗,否则会弹出两次弹窗
              return true;
          }
      });
      
      btnTest.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              // 调用js中的test函数
              hwvContent.js("test", "小姐姐");
          }
      });
    • 自定义属性

      属性 说明 默认值
      hwv_strict_mode 是否使用严格模式(需要严格匹配url参数) false
      hwv_url_flag_name URL标识名称 platform
      hwv_url_flag_value URL标识值 app
      hwv_bridge_name 交互桥梁名称 app
      hwv_cache_enable 是否开启缓存 true
      hwv_cache_expire 缓存保存时间,单位:s 一周
  • CheckBox

    带动画效果的多选框

    • 布局文件

      <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:gravity="center"
        android:orientation="horizontal">
      
        <com.yhy.widget.core.checked.CheckBox
          android:id="@+id/cb_cancel"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:cb_color_checked="@color/colorPrimary"
          app:cb_color_tick="@color/textPrimary"
          app:cb_color_unchecked="@color/windowBackground"
          app:cb_color_unchecked_stroke="@color/colorLine"
          app:cb_duration="1000"
          app:cb_stroke_width="4dp"
          app:cb_click_cancel_able="false" />
      
        <TextView
          android:id="@+id/tv_cancel"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginLeft="8dp"
          android:text="选中后点击我来取消"
          android:textColor="@color/textPrimary"
          android:textSize="14sp" />
      </nearLayout>
    • 获取控件

      CheckBox cbCancel = $(R.id.cb_cancel);
      TextView tvCancel = $(R.id.tv_cancel);
    • 设置事件

      cbCancel.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
          @Override
          public void onCheckedChanged(CheckBox checkBox, boolean isChecked) {
              toast("是否选中:" + isChecked);
          }
      });
      
      tvCancel.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              // 切换
              cbCancel.toggle();
          }
      });
    • 自定义属性

      属性 说明 默认值
      cb_duration 动画时长,单位:ms 300
      cb_stroke_width 边框宽度,单位:dp 0
      cb_color_tick 打钩图标颜色 #ffffff
      cb_color_checked 选中时的颜色 #fb4846
      cb_color_unchecked 未选中时的颜色 #ffffff
      cb_color_unchecked_stroke 未选中时边框的颜色 #dfdfdf
      cb_click_cancel_able 是否可点击取消 true
  • StatusDialog

    各状态【加载中|成功|失败|错误】弹窗提示

    不用布局文件

    • Common

      所有弹窗都继承了AbsStatusDialog,提供抽象方法View statusView(),用来从子类获取具体的状态View

      【成功|失败|错误】三种弹窗继承于AbsUnableCancelStatusDialog,其内部禁用了弹窗取消事件,且也继承于AbsStatusDialog默认弹出3s后自动消失,具体时间可以在构造方法参数控制

      各弹窗都可以自定义弹窗图标部分,重写父类的View statusView()方法,返回具体的View即可

      // 顶级抽象类
      public abstract class AbsStatusDialog extends AlertDialog { ... }
      
      // 禁止取消抽象类
      public abstract class AbsUnableCancelStatusDialog extends AbsStatusDialog { ... }
      
      // 加载中状态,直接继承于顶级抽象类
      public class LoadingDialog extends AbsStatusDialog { ... }
      
      // 成功状态,继承于禁止取消抽象类
      public class SuccessDialog extends AbsUnableCancelStatusDialog { ... }
      
      // 失败状态,继承于禁止取消抽象类
      public class FailedDialog extends AbsUnableCancelStatusDialog { ... }
      
      // 错误状态,继承于禁止取消抽象类
      public class ErrorDialog extends AbsUnableCancelStatusDialog { ... }
    • 加载中弹窗

      重写了父类的statusView()方法,返回了默认的ProgressBar控件

      未禁止返回取消弹窗,已禁止点击外部取消弹窗

      LoadingDialog dialog = new LoadingDialog(getContext());
      dialog.setText("加载中...");
      // 或者直接构造方法这样写
      LoadingDialog dialog = new LoadingDialog(getContext(), "加载中...");
      dialog.setCancelable(true, false);
      dialog.setText("...");
      dialog.show();
      
      // 取消弹窗
      dialog.dismiss();
    • 【成功|失败|错误】

      这三种状态用法一致,只是要用不同的类而已

      已禁止所有的手动取消事件,默认为显示后1s后消失,该时间可自定义

      // 成功
      SuccessDialog dialog = new SuccessDialog(getContext(), "加载成功", 1000);
      // 失败
      FailedDialog dialog = new FailedDialog(getContext(), "加载失败", 1000);
      // 错误
      ErrorDialog dialog = new ErrorDialog(getContext(), "加载错误", 1000);
      
      // 设置文本
      dialog.setText("...");
      
      // 显示3s后自动消失
      dialog.show();
    • 状态弹窗管理器

      这里提供个默认的弹窗管理器StatusDialogManager,用来管理各种弹窗并处理其表现形式

      其用法如下

      // 创建管理器
      StatusDialogManager manager = StatusDialogManager.with(this)
          .loadingText("正在加载...")
          .successText("成功啦")
          .failedText("失败咯")
          .errorText("出错啦")
          .enableLoadingCancel(true)
          .duration(3000)
          .create();
      
      // 触发控制各种弹窗事件
      tvLoading.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              manager.loading();
              // 或者
              manager.loading("加载中,哈哈...");
              new Handler().postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      mManager.dismiss();
                  }
              },3000);
          }
      });
      
      tvSuccess.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              manager.success();
              // 或者
              manager.success("成功啦,哈哈");
          }
      });
      
      tvFailed.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              manager.failed();
              // 或者
              manager.failed("成功啦,哈哈");
          }
      });
      
      tvError.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              manager.error();
              // 或者
              manager.error("成功啦,哈哈");
          }
      });
  • InputDialogView

    输入框弹窗,比如聊天输入框,评论输入框等

    不用布局文件

    • 显示弹窗

      // 显示输入框弹窗
      // builder 可配置弹窗的各种颜色和相关字体大小等属性
      InputDialogView.Builder builder = new InputDialogView.Builder(InputDialogActivity.this);
      builder.hint(position % 2 != 0 ? "回复" + mDataList.get(position) : "说点儿什么呀...")
          .contentSize(14)
          .anchor(itemView) // 弹窗需要参考的view,弹出后回调方法onShow()中传回弹窗与该view的坐标偏移值
          .listener(new InputDialogView.OnInputDialogListener() {
              @Override
              public void onPublish(InputDialogView dialog, CharSequence content) {
                  dialog.dismiss();
                  toast(content);
              }
      
              @Override
              public void onShow(int offsetX, int offsetY, int[] position) {
                  // 点击某条评论则这条评论刚好在输入框上面,点击评论按钮则输入框刚好挡住按钮
                  rvContent.smoothScrollBy(0, offsetY, new AccelerateDecelerateInterpolator());
              }
      
              @Override
              public void onDismiss() {
              }
          });
      builder.build().show();
  • ConstraintImageView

    按宽高比来约束大小的ImageView,还可以设置圆角及边框等

    分为两种模式:以width或者height为基准,计算另一边大小,默认以width为准

    注意:宽高比直接设置成 规定图片的宽与高即可

    • 布局文件

      <!-- 以width为准,宽高比为:720:300 -->
      <com.yhy.widget.core.img.ConstraintImageView
        android:id="@+id/civ_width"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/ic_avatar"
        app:civ_original_ratio="720:300"
        app:civ_reference="width" />
      
      <!-- 以height为准,宽高比为:200:300 -->
      <com.yhy.widget.core.img.ConstraintImageView
        android:id="@+id/civ_height"
        android:layout_width="wrap_content"
        android:layout_height="240dp"
        android:layout_marginTop="16dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/ic_avatar"
        app:civ_original_ratio="200:300"
        app:civ_reference="height" />
      
      <!-- 默认以width为准,逐个设置各个角落的圆角半径 -->
      <com.yhy.widget.core.img.ConstraintImageView
        android:id="@+id/civ_a"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_avatar"
        app:civ_border_color="#8c9eff"
        app:civ_border_width="2dp"
        app:civ_radius_left_bottom="30dp"
        app:civ_radius_right_top="30dp"
        app:civ_ratio="0.75" />
      
      <!-- 默认以width为准,统一设置各个角落的圆角半径 -->
      <com.yhy.widget.core.img.ConstraintImageView
        android:id="@+id/civ_test"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:layout_marginTop="16dp"
        android:src="@mipmap/ic_avatar"
        app:civ_radius="12dp"
        app:civ_ratio="0.5"
        app:civ_reference="height" />
    • 获取控件

      ConstraintImageView civWidth = $(R.id.civ_width);
      ConstraintImageView civHeight = $(R.id.civ_height);
      ConstraintImageView civA = $(R.id.civ_a);
      ConstraintImageView civTest = $(R.id.civ_test);
    • 设置数据

      ImgUtils.load(this, civWidth, ImgUrls.getAImgUrl());
      ImgUtils.load(this, civHeight, ImgUrls.getAImgUrl());
      ImgUtils.load(this, civA, ImgUrls.getAImgUrl());
      ImgUtils.load(this, civTest, ImgUrls.getAImgUrl());
      
      // 动态设置图片真实宽高比例(三种重载方式)
      civWidth.setRatio(1.5f);
      civHeight.setRatio("250:300");
      civTest.setRatio(400, 400);
    • 自定义属性

      属性 说明 默认值
      civ_reference 参考标准,以【widthheight】为准,计算另一方向的实际值 width
      civ_original_ratio 比例字符串,图片实际的宽高即可,格式:“宽:高”
      civ_ratio 图片真实宽高比例值,格式:“0.75 0
      civ_radius 四个角半径,单位:dp 0
      civ_radius_left_top 左上角半径,单位:dp 0
      civ_radius_right_top 右上角半径,单位:dp 0
      civ_radius_right_bottom 右下角半径,单位:dp 0
      civ_radius_left_bottom 左下角半径,单位:dp 0
      civ_border_width 边框宽度,单位:dp 0
      civ_border_color 边框颜色 #000000
  • GradientTextView

    文字带渐变动画的TextView

    • 布局文件

      <com.yhy.widget.core.text.GradientTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="默认样式"
        android:textSize="16sp" />
      
      <com.yhy.widget.core.text.GradientTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="自定义颜色"
        android:textSize="16sp"
        app:gtv_text_color_list="@array/color_arr_test" />
        
      <com.yhy.widget.core.text.GradientTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="自定义颜色和刷新速度"
        android:textSize="16sp"
        app:gtv_speed_millions="100"
        app:gtv_text_color_list="@array/color_arr_test" />
    • 自定义属性

      属性 说明 默认值
      gtv_speed_millions 刷新颜色动画的时间间隔,单位:ms 200
      gtv_text_color_list 需要渐变的颜色数组 @array/color_arr_gradient_text_view
    • 自定义颜色数组res/values/arrays.xml

      <integer-array name="color_arr_test">
          <!--integer-array,这里不能直接写16进制的颜色代码,否则报错-->
          <item>@color/red</item>
          <item>@color/red_light</item>
          <item>@color/orange</item>
          <item>@color/red_light</item>
          <item>@color/red</item>
      </integer-array>
  • LineTextView

    加各种线条的TextView,比如下划线,删除线等

    • 布局文件

      <com.yhy.widget.core.text.LineTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="默认长这个样子"
        android:textColor="@color/textPrimary"
        android:textSize="16sp" />
      
      <com.yhy.widget.core.text.LineTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="1dp的下划线"
        android:textColor="@color/textPrimary"
        android:textSize="16sp"
        app:ltv_line_size="1dp" />
      
      <com.yhy.widget.core.text.LineTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="1dp的中间删除线"
        android:textColor="@color/textPrimary"
        android:textSize="16sp"
        app:ltv_line_size="1dp"
        app:ltv_line_style="delete_middle" />
      
      <com.yhy.widget.core.text.LineTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="1dp的对角删除线"
        android:textColor="@color/textPrimary"
        android:textSize="16sp"
        app:ltv_line_size="1dp"
        app:ltv_line_style="delete_oblique" />
    • 自定义属性

      属性 说明 默认值
      ltv_line_size 线条宽度,单位:dp 0
      ltv_line_color 线条颜色 #000000
      ltv_line_interval 线条间隔,该属性只在下划线风格中有效,单位:dp 0
      ltv_line_style 线条风格【underlinedelete_middledelete_oblique underline

layout控件

  • CheckedFrameLayout

    可选中的FrameLayout

    • 布局文件

      <com.yhy.widget.layout.checked.CheckedRelativeLayout
        android:id="@+id/crl_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
      
        <TextView
          android:id="@+id/tv_test"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:background="@drawable/bg_checked_ctv_selector"
          android:padding="8dp"
          android:text="CheckedRelativeLayout"
          android:textColor="#fff"
          android:textSize="14sp" />
      
        <TextView
          android:layout_below="@id/tv_test"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginTop="48dp"
          android:background="@drawable/bg_checked_ctv_selector"
          android:padding="8dp"
          android:text="CheckedRelativeLayout"
          android:textColor="#fff"
          android:textSize="14sp" />
      </com.yhy.widget.layout.checked.CheckedRelativeLayout>
    • 获取控件

      CheckedRelativeLayout crlTest = $(R.id.crl_test);
      CheckedRelativeLayout tvTest = $(R.id.tv_test);
    • 设置事件

      tvTest.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          toast("点击了TextView");
        }
      });
      
      crlTest.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          toast("点击");
        }
      });
      
      crlTest.setOnCheckedChangeListener(new CheckedRelativeLayout.OnCheckedChangeListener() {
        @Override
        public void onChanged(CheckedRelativeLayout crl, boolean isChecked) {
          toast("isChecked = " + isChecked);
        }
      });
  • CheckedLayout

    可选中的ViewGroup

    用法同CheckedFrameLayout

  • CheckedLinearLayout

    可选中的LinearLayout

    用法同CheckedFrameLayout

  • CheckedRelativeLayout

    可选中的RelativeLayout

    用法同CheckedFrameLayout

  • FlowLayout

    流式布局

    一般不用这个布局,只在定义其他流式布局时使用,继承FlowLayout即可,详情请参照TagFlowLayout源码

    • 布局文件

      <com.yhy.widget.layout.flow.FlowLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
      
        <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_margin="8dp"
          android:background="#666"
          android:padding="4dp"
          android:text="哈哈哈哈"
          android:textColor="#fff"
          android:textSize="14sp" />
      
        <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_margin="8dp"
          android:background="#666"
          android:padding="4dp"
          android:text="呵哈呵"
          android:textColor="#fff"
          android:textSize="14sp" />
      
        <!-- 多个子控件... -->
      </com.yhy.widget.layout.flow.FlowLayout>
    • 自定义属性

      属性 说明 默认值
      fl_gravity 布局对齐方式 left
  • TagFlowLayout

    标签流式布局

    继承于FlowLayout

    • 布局文件

      <com.yhy.widget.layout.flow.tag.TagFlowLayout
        android:id="@+id/tfl_def"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    • 获取控件

      // 泛型表示该控件中数据源的数据类型
      TagFlowLayout<TestEntity> tflDef = findViewById(R.id.tfl_def);
    • 设置数据和事件

      // 模拟数据
      List<TestEntity> mTestList = new ArrayList<>();
      mTestList.add(new TestEntity(0, "张三张三张三张三张三"));
      mTestList.add(new TestEntity(1, "李四"));
      mTestList.add(new TestEntity(2, "大胖子"));
      mTestList.add(new TestEntity(3, "尼古拉斯"));
      mTestList.add(new TestEntity(4, "哈"));
      mTestList.add(new TestEntity(5, "大胖子"));
      mTestList.add(new TestEntity(6, "尼古拉斯"));
      mTestList.add(new TestEntity(7, "哈"));
      
      // 设置适配器
      tflDef.setAdapter(new TagFlowAdapter<TestEntity> {
        public Adapter(List<TestEntity> dataList) {
          super(dataList);
        }
      
        @Override
        public View getView(TagFlowLayout parent, int position, TestEntity data) {
          TextView tv = (TextView) LayoutInflater.from(TagFlowActivity.this).inflate(R.layout.item_tag_flow, null);
          tv.setText(data.name);
          return tv;
        }
      });
      
      // 设置条目点击事件
      tflDef.setOnCheckChangedListener(new TagFlowLayout.OnCheckChangedListener<TestEntity>() {
        @Override
        public void onChanged(boolean checked, int position, TestEntity data, List<TestEntity> dataList) {
          toast(dataList);
          // 动态添加元素
          mTestList.add(new TestEntity(9, "嘻嘻嘻" + position));
          mAdapter.notifyDataChanged();
        }
      });
    • 自定义属性

      属性 说明 默认值
      fl_gravity 布局对齐方式 left
      tfl_max_count 允许选中的最大数量,-1表示无限 -1
      tfl_is_single 是否是单选 false
  • SlideLayout

    侧滑菜单布局

    • 布局文件

      <com.yhy.widget.layout.slider.SlideLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/sl_slide"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/bg_main"
        app:sl_anim_alpha_color="#f60"
        app:sl_main_alpha_enable="true">
      
        <LinearLayout
          android:layout_width="240dp"
          android:layout_height="match_parent"
          android:background="#66000000"
          android:gravity="center"
          android:orientation="vertical">
      
          <TextView
            android:id="@+id/tv_menu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="菜单"
            android:textColor="#f40"
            android:textSize="24sp" />
        </LinearLayout>
      
        <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="#fff"
          android:orientation="vertical">
      
          <android.support.v4.view.ViewPager
            android:id="@+id/vp_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        </LinearLayout>
      </com.yhy.widget.layout.slider.SlideLayout>
    • 获取控件

      SlideLayout slSlide = findViewById(R.id.sl_slide);
      TextView tvMenu = findViewById(R.id.tv_menu);
      ViewPager vpContent = findViewById(R.id.vp_content);
    • 设置数据和事件

      // 为ViewPager设置适配器
      vpContent.setAdapter(new PagerAdapter() {
        @Override
        public int getCount() {
          return 4;
        }
      
        @Override
        public boolean isViewFromObject(View view, Object object) {
          return view == object;
        }
      
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
          ImageView iv = new ImageView(SliderActivity.this);
          iv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
          iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
          if (position == 0) {
            iv.setImageResource(R.mipmap.img_pager_1);
          } else if (position == 1) {
            iv.setImageResource(R.mipmap.img_pager_2);
          } else if (position == 2) {
            iv.setImageResource(R.mipmap.img_pager_3);
          } else {
            iv.setImageResource(R.mipmap.img_pager_4);
          }
          container.addView(iv);
          return iv;
        }
      
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
          container.removeView((View) object);
        }
      });
      
      // 设置事件
      // 当菜单按钮点击时关闭菜单
      tvMenu.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          slSlide.close();
        }
      });
      
      // 监听内容,根据需要改变侧滑菜单的可用性
      slSlide.setOnSlideEnableWatcher(new SlideLayout.OnSlideEnableWatcher() {
        @Override
        public boolean shouldEnable() {
          //第二页禁用侧边栏
          return vpContent.getCurrentItem() != 1;
        }
      });
      
      // 菜单滑动状态监听
      slSlide.setOnStateChangeListener(new SlideLayout.OnStateChangeListener() {
        @Override
        public void onOpened() {
          tvMenu.setText("已打开");
        }
      
        @Override
        public void onClosed() {
          tvMenu.setText("已关闭");
        }
      
        @Override
        public void onDragging(float percent, int dx, int total) {
          tvMenu.setText("比例:" + percent);
        }
      });
  • StatusLayout

    状态管理页面布局【加载中,空数据,错误,成功】

    共有三种使用方法,分别是【默认,布局文件中配置,使用外部助手配置】

    多种使用方式的优先级关系为:布局文件中配置 > 使用外部助手配置 > 默认

    • 注意

      四种状态均用tag来做区分,所以必须要给各种页面设置对应的tag

      状态 tag
      加载中 loading
      空数据 empty
      错误 error
      成功 success
    • 默认方式

      • 布局文件

        <com.yhy.widget.layout.status.StatusLayout
          android:id="@+id/sl_content"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="#fff">
        
          <!--当只有一个子控件时,该子控件会被当作[成功]状态的界面,此时无需指定tag为success-->
          <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:tag="success">
        
            <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Success"
              android:textColor="#2f0"
              android:textSize="20sp" />
          </LinearLayout>
        </com.yhy.widget.layout.status.StatusLayout>
    • 布局文件中配置

      • 布局文件

        <com.yhy.widget.layout.status.StatusLayout
          android:id="@+id/sl_content"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="#fff">
        
          <!-- 默认的加载中页面 -->
          <com.yhy.widget.layout.status.view.StaLoadingView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:tag="loading" />
        
          <!-- 默认的错误页面 -->
          <com.yhy.widget.layout.status.view.StaErrorView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:tag="error" />
        
          <!-- 默认的空数据页面 -->
          <com.yhy.widget.layout.status.view.StaEmptyView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:tag="empty" />
        
          <!-- 成功页面 -->
          <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:tag="success">
        
            <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Success"
              android:textColor="#2f0"
              android:textSize="20sp" />
          </LinearLayout>
        </com.yhy.widget.layout.status.StatusLayout>
    • 使用外部助手配置

      • 布局文件

        <com.yhy.widget.layout.status.StatusLayout
          android:id="@+id/sl_content"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="#fff">
        
          <!-- 使用外部助手配置时,也可以在布局中配置,布局中优先使用 -->
          <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:tag="error">
        
            <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:gravity="center"
              android:tag="retry"
              android:text="布局中定义的错误页面"
              android:textColor="#246854"
              android:textSize="20sp" />
          </LinearLayout>
        
          <!-- 成功页面 -->
          <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:tag="success">
        
            <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Success"
              android:textColor="#2f0"
              android:textSize="20sp" />
          </LinearLayout>
        </com.yhy.widget.layout.status.StatusLayout>
      • 获取控件

        StatusLayout slContent = findViewById(R.id.sl_content);
      • 外部助手配置

        StaLayoutHelperBuilder builder = new StaLayoutHelperBuilder.Builder(slContent).setLoadingLayout(getLoadingView()).build();
        // builder 还可以设置各种状态的view
        slContent.setHelper(builder.getHelper());
        
        // ...
        private View getLoadingView() {
          TextView tv = new TextView(this);
          tv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
          tv.setText("Helper中定义的加载中");
          tv.setGravity(Gravity.CENTER);
          tv.setTextSize(18);
          tv.setTextColor(Color.RED);
          // 设置tag为loading
          tv.setTag(StatusLayout.Status.LOADING.getStatus());
          return tv;
        }
    • 切换页面状态

      // 加载中
      slContent.showLoading();
      // 成功
      slContent.showSuccess();
      // 错误
      slContent.showError();
      // 空数据
      slContent.showEmpty();

一些颜色

预定义的一些颜色

<resources>
    <color name="colorPrimary">#01aca8</color>
    <color name="colorAccent">#fe4365</color>
    <color name="colorLoading">#113e3c</color>
    <color name="windowBackground">#eeeeee</color>
    <color name="colorDisabled">#ababab</color>
    <color name="colorLine">#999999</color>
    <color name="textPrimary">#1d294c</color>
    <color name="textAccent">#24211c</color>
    <color name="alphaBlack">#88000000</color>
    <color name="alphaWhite">#88ffffff</color>
</resources>

That's all, enjoy it !!!

License

Copyright 2019 yhyzgn

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

About

封装了一些常用的自定义View,用于快捷开发

License:Apache License 2.0


Languages

Language:Java 98.1%Language:JavaScript 1.5%Language:HTML 0.4%