<commit_before># `NavView`

### 1. 简单用法

- 第一步，再布局文件中使用控件

  ```xml
  <com.yhy.tpg.widget.NavView
      android:id="@+id/tv_content"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
  ```

- 第二步，设置底部导航元素‘

  ```java
  private static final List<NavTab> TAB_LIST = new ArrayList<>();
  ...
    
    TAB_LIST.add(new NavTab("首页", R.drawable.tab_home_selector));
    TAB_LIST.add(new NavTab("贷款", R.drawable.tab_loan_selector));
    TAB_LIST.add(new NavTab("通知", R.drawable.tab_notice_selector));
    TAB_LIST.add(new NavTab("我的", R.drawable.tab_mine_selector));

  ...
  ```

- 第二步，给`NavView`设置适配器（“页面参数”在扩展中介绍）

  ```java
  //获取到布局中的控件
  bvContent = (NavView) findViewById(R.id.bv_content);

  //设置适配器
  mAdapter = new ContentAdapter(getSupportFragmentManager(), TAB_LIST, mConfig);
  bvContent.setAdapter(mAdapter);

  //内部类中定义适配器
  private class ContentAdapter extends NavAdapter {
    public ContentAdapter(FragmentManager fm, List<NavTab> tabList, PagerConfig config) {
      super(fm, tabList, config);
    }

    @Override
    public TpgFragment getPager(int position) {
      Bundle args = new Bundle();
      args.putBoolean("isHybrid", false);
      args.putBoolean("firstPage", position == 0);
      TpgFragment fragment = new NavPager();
      fragment.setArguments(args);
      return fragment;
    }

    @Override
    public int getCount() {
      return TAB_LIST.size();
    }
  }
  ```

- 第四步，在具体页面类必须继承自`TpgFragment`，实现抽象方法`getSuccessView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)`，并返回加载成功时的页面（以`NavPager.java`为例）

  ```java
  public class NavPager extends TpgFragment {
    ...
      
    @Override
    protected View getSuccessView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      TextView tv = new TextView(getContext());
      tv.setText("Nav页面加载成功");
      tv.setTextColor(Color.RED);
      tv.setTextSize(32);
      tv.setGravity(Gravity.CENTER);
      //返回加载成功时的页面
      return tv;
    }
    
    ...
  }
  ```

- 第五步，实现抽象方法`initData()`，将数据请求部分的操作放在该方法中，便于`NavView`获取到数据加载结果状态。但是加载结果必须要用父类的成员变量`mRltHandler`来操作...

  ```java
  @Override
  protected void initData() {
    //请求服务器数据
    getDataFromServer();
  }

  @Override
  protected void initListener(){
    //初始化一些事件监听
  }

  //模拟请求服务器数据过程
  private void getDataFromServer() {
    //用来产生一个随机的状态
    final Random random = new Random();
    new Thread() {
      @Override
      public void run() {
        //模拟网络加载延迟
        SystemClock.sleep(3000);

        //数据加载结束后，需要手动刷新页面状态
        int temp = random.nextInt(3);
        switch (temp) {
          case 0:
            //如果加载成功，就发送成功的Handler
            mRltHandler.sendSuccessHandler();
            break;
          case 1:
            //加载失败，发送错误Handler
            mRltHandler.sendErrorHandler();
            break;
          case 2:
            //数据为空，发送空数据Handler
            mRltHandler.sendEmptyHandler();
            break;
          default:
            break;
        }
      }
    }.start();
  }
  ```

  以上就是简单用法的详细步骤 :joy::joy:

------

### 3. 扩展

- 自定义属性

  > 在布局文件中自行定义

  | 属性名                      | 属性说明             | 默认值       |
  | :----------------------- | :--------------- | :-------- |
  | `nav_bg_color`           | 导航栏背景色           | 透明        |
  | `nav_bg_img`             | 导航栏背景图片          | 无         |
  | `nav_text_default_color` | 普通状态下选项字体颜色      | `#000000` |
  | `nav_text_checked_color` | 选中状态下选项字体颜色      | `#000000` |
  | `nav_bg_checked_color`   | 选中状态下选项背景颜色      | 透明        |
  | `nav_bg_checked_img`     | 选中状态下选项背景图片      | 无         |
  | `nav_divider_line_color` | 导航栏与内容页面之间的分割线颜色 | 透明，不显示    |
  | `nav_scroll_able`        | 是否可滑动            | `true`    |

- 如果第一页数据未自动加载

  > 由于数据加载方法时在`ViewPager`页面切换后才被回调的，而控件第一次加载时不会触发页面切换，所以只能手动加载第一页数据。通过封装后，只需要重写父类的`shouldLoadDataAtFirst()`方法，并返回`true`即可自动加载该页数据。

  ```java
  @Override
  public boolean shouldLoadDataAtFirst() {
    return true;<commit_msg>更新说明文档<commit_after># `NavView`

### 1. 简单用法

- 第一步，再布局文件中使用控件

  ```xml
  <com.yhy.tpg.widget.NavView
      android:id="@+id/tv_content"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
  ```

- 第二步，设置底部导航元素‘

  ```java
  private static final List<NavTab> TAB_LIST = new ArrayList<>();
  ...
    
    TAB_LIST.add(new NavTab("首页", R.drawable.tab_home_selector));
    TAB_LIST.add(new NavTab("贷款", R.drawable.tab_loan_selector));
    TAB_LIST.add(new NavTab("通知", R.drawable.tab_notice_selector));
    TAB_LIST.add(new NavTab("我的", R.drawable.tab_mine_selector));

  ...
  ```

- 第二步，给`NavView`设置适配器（“页面参数”在扩展中介绍）

  ```java
  //获取到布局中的控件
  bvContent = (NavView) findViewById(R.id.bv_content);

  //设置适配器
  mAdapter = new ContentAdapter(getSupportFragmentManager(), TAB_LIST, mConfig);
  bvContent.setAdapter(mAdapter);

  //内部类中定义适配器
  private class ContentAdapter extends NavAdapter {
    public ContentAdapter(FragmentManager fm, List<NavTab> tabList, PagerConfig config) {
      super(fm, tabList, config);
    }

    @Override
    public TpgFragment getPager(int position) {
      Bundle args = new Bundle();
      args.putBoolean("isHybrid", false);
      args.putBoolean("firstPage", position == 0);
      TpgFragment fragment = new NavPager();
      fragment.setArguments(args);
      return fragment;
    }

    @Override
    public int getCount() {
      return TAB_LIST.size();
    }
  }
  ```

- 第四步，在具体页面类必须继承自`TpgFragment`，实现抽象方法`getSuccessView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)`，并返回加载成功时的页面（以`NavPager.java`为例）

  ```java
  public class NavPager extends TpgFragment {
    ...
      
    @Override
    protected View getSuccessView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      TextView tv = new TextView(getContext());
      tv.setText("Nav页面加载成功");
      tv.setTextColor(Color.RED);
      tv.setTextSize(32);
      tv.setGravity(Gravity.CENTER);
      //返回加载成功时的页面
      return tv;
    }
    
    ...
  }
  ```

- 第五步，实现抽象方法`initData()`，将数据请求部分的操作放在该方法中，便于`NavView`获取到数据加载结果状态。但是加载结果必须要用父类的成员变量`mRltHandler`来操作...

  ```java
  @Override
  protected void initData() {
    //请求服务器数据
    getDataFromServer();
  }

  @Override
  protected void initListener(){
    //初始化一些事件监听
  }

  //模拟请求服务器数据过程
  private void getDataFromServer() {
    //用来产生一个随机的状态
    final Random random = new Random();
    new Thread() {
      @Override
      public void run() {
        //模拟网络加载延迟
        SystemClock.sleep(3000);

        //数据加载结束后，需要手动刷新页面状态
        int temp = random.nextInt(3);
        switch (temp) {
          case 0:
            //如果加载成功，就发送成功的Handler
            mRltHandler.sendSuccessHandler();
            break;
          case 1:
            //加载失败，发送错误Handler
            mRltHandler.sendErrorHandler();
            break;
          case 2:
            //数据为空，发送空数据Handler
            mRltHandler.sendEmptyHandler();
            break;
          default:
            break;
        }
      }
    }.start();
  }
  ```

  以上就是简单用法的详细步骤 :joy::joy:

------

### 3. 扩展

- 自定义属性

  > 在布局文件中自行定义

  | 属性名                      | 属性说明             | 默认值       |
  | :----------------------- | :--------------- | :-------- |
  | `nav_bg_color`           | 导航栏背景色           | 透明        |
  | `nav_height`             | 导航栏高度            | `48dp`    |
  | `nav_bg_img`             | 导航栏背景图片          | 无         |
  | `nav_text_default_color` | 普通状态下选项字体颜色      | `#000000` |
  | `nav_text_checked_color` | 选中状态下选项字体颜色      | `#000000` |
  | `nav_bg_checked_color`   | 选中状态下选项背景颜色      | 透明        |
  | `nav_bg_checked_img`     | 选中状态下选项背景图片      | 无         |
  | `nav_divider_line_color` | 导航栏与内容页面之间的分割线颜色 | 透明，不显示    |
  | `nav_scroll_able`        | 是否可滑动            | `true`    |

- 如果第一页数据未自动加载

  > 由于数据加载方法时在`ViewPager`页面切换后才被回调的，而控件第一次加载时不会触发页面切换，所以只能手动加载第一页数据。通过封装后，只需要重写父类的`shouldLoadDataAtFirst()`方法，并返回`true`即可自动加载该页数据。

  ```java
  @Override
  public boolean shouldLoadDataAtFirst() {
    return true;
{'fraction_non_alphanumeric': 0.13513175971025354, 'fraction_numerical': 0.006494317472211814, 'mean_word_length': 2.3173156586578294, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '54930', 'n_tokens_mistral': 3383, 'n_tokens_neox': 3552, 'n_words': 434}