Skip to content

xuexiangjys/XPage

Folders and files

NameName
Last commit message
Last commit date
Jun 12, 2019
Jan 10, 2021
Aug 27, 2023
May 11, 2023
Aug 8, 2021
Jun 3, 2018
May 11, 2023
Aug 8, 2021
Jan 9, 2021
Aug 27, 2023
Aug 27, 2023
Dec 1, 2019
Aug 15, 2018
May 11, 2023
Dec 9, 2020
Jul 12, 2020
Jan 7, 2018
Jan 7, 2018
Jan 9, 2021
Aug 10, 2021

Repository files navigation

XPage

api I Star

一个非常方便的Fragment页面框架!还不赶紧点击使用说明文档,体验一下吧!

另外,你还可以参见XPage视频教程进行学习。

关于我

公众号 掘金 知乎 CSDN 简书 思否 哔哩哔哩 今日头条
我的Android开源之旅 点我 点我 点我 点我 点我 点我 点我

X系列库快速集成

为了方便大家快速集成X系列框架库,我提供了一个空壳模版供大家参考使用: https://github.com/xuexiangjys/TemplateAppProject

除此之外,我还特别制作了几期X系列视频教程供大家学习参考.


特征

  • 支持assets下“corepage.json”静态配置Fragment页面信息。
  • 支持Application中动态配置Fragment页面信息。
  • 支持通过注解@Page的方式动态自动配置页面信息。
  • 支持自定义Fragment页面信息配置。
  • 支持4种默认Fragment页面切换动画。
  • 支持Fragment页面间参数传递。
  • 支持Fragment页面属性保存。
  • 支持Fragment页面的onKeyDown、onFragmentResult等生命周期
  • 支持Fragment和Fragment页面自由跳转以及数据交互。
  • 支持导航栏通过注解的方式自动添加及设置。
  • 支持自定义TitleBar全局主题属性。
  • 支持自定义Fragment页面容器。
  • 支持自定义Activity页面容器。
  • 支持Fragment之间、activity和fragment之间的数据交互。
  • 兼容kotlin和androidx。

Star趋势图

Stargazers over time

1、演示(请star支持)

xpage.gif

Demo下载

downloads


2、如何使用

目前支持主流开发工具AndroidStudio的使用,直接配置build.gradle,增加依赖即可.

2.1、Android Studio导入方法,添加Gradle依赖

1.先在项目根目录的 build.gradlerepositories 添加:

allprojects {
     repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

2.然后在应用项目(一般是app)的 build.gradle 的 dependencies 添加:

以下是版本说明,选择一个即可。

  • androidx版本:3.0.0及以上
dependencies {
  ...
  // XPage
  implementation 'com.github.xuexiangjys.XPage:xpage-lib:3.4.0'
  annotationProcessor 'com.github.xuexiangjys.XPage:xpage-compiler:3.4.0'
}

【版本注意】3.3.0及以上版本去除了ButterKnife的依赖。

【升级注意】从 3.3.0以下 升级到 3.4.0及以上:

    @Deprecated
    protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);

------> 替换为

    protected abstract View onCreateContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, boolean attachToRoot);
  • support版本:2.3.0及以下
dependencies {
  ...
  // XPage
  implementation 'com.github.xuexiangjys.XPage:xpage-lib:2.3.0'
  annotationProcessor 'com.github.xuexiangjys.XPage:xpage-compiler:2.3.0'
  // ButterKnife的sdk
  implementation 'com.jakewharton:butterknife:8.4.0'
  annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
}

【注意】如果你使用的是kotlin,请使用如下配置:

apply plugin: 'kotlin-kapt'

dependencies {
  ...
  //XPage
  implementation 'com.github.xuexiangjys.XPage:xpage-lib:3.4.0'
  kapt 'com.github.xuexiangjys.XPage:xpage-compiler:3.4.0'
}

【注意】:如果你使用的module不止一个的话,每个module下都需要增加XPage的依赖。

3.进行moduleName注册

defaultConfig {
    ...

    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [ moduleName : project.getName() ]
        }
    }
}

【注意】:如果不注册的话,默认ModuleName为app

2.2、页面注册

2.2.1、assets中静态注册

在assets文件夹中新建“corepage.json“,然后进行如下配置:

[
  {
    "name": "测试页面1",
    "classPath": "com.xuexiang.xpagedemo.fragment.TestFragment1",
    "params": ""
  },
  {
    "name": "测试页面2",
    "classPath": "com.xuexiang.xpagedemo.fragment.TestFragment2",
    "params": {
      "key1":"这是参数1的值",
      "key2":"这是参数2的值"
    }
  },
]

2.2.2、Application中动态注册【推荐】

1.自动进行页面注册【推荐】

使用apt编译时自动生成的页面注册配置类 "moduleName"+PageConfig 的getPages()进行注册。

PageConfig.getInstance()
//      //页面注册,默认不设置的话使用的就是自动注册
//      .setPageConfiguration(new AutoPageConfiguration())
        .debug("PageLog")       //开启调试
        .setContainActivityClazz(XPageActivity.class) //设置默认的容器Activity
        .init(this);            //初始化页面配置

【注意】:如果你的项目中只是增加了依赖,还没有使用@Page注解XPageFragment页面的话,在编译时是不会自动生成注册页面的!!

2.手动动态进行页面注册

PageConfig.getInstance()
        .setPageConfiguration(new PageConfiguration() { //页面注册
            @Override
            public List<PageInfo> registerPages(Context context) {
                List<PageInfo> pageInfos = new ArrayList<>();
                addPageInfoAndSubPages(pageInfos, MainFragment.class);
                pageInfos.add(PageConfig.getPageInfo(DateReceiveFragment.class));
                return pageInfos;        //手动注册页面
            }
        })
        .debug("PageLog")       //开启调试
        .init(this);            //初始化页面配置

2.3、使用PageOption进行页面操作【推荐】

使用PageOption.to进行页面选项构建。

PageOption.to(TestFragment.class) //跳转的fragment
    .setAnim(CoreAnim.zoom) //页面跳转动画
    .setRequestCode(100) //请求码,用于返回结果
    .setAddToBackStack(true) //是否加入堆栈
    .setNewActivity(true, ContainActivity.class) //是否使用新的Activity打开
    .putBoolean(DateReceiveFragment.KEY_IS_NEED_BACK, true) //传递的参数
    .open(this); //打开页面进行跳转

2.4、页面跳转

使用XPage,Activity必须要继承XPageActivity,Fragment必须要继承XPageFragment,否则将无法调用页面跳转的openPage方法。

2.4.1、携带数据

Bundle params = new Bundle();
switch(position) {
    case 0:
        params.putBoolean(DateReceiveFragment.KEY_IS_NEED_BACK, false);
        int id = (int) (Math.random() * 100);
        params.putString(DateReceiveFragment.KEY_EVENT_NAME, "事件" + id);
        params.putString(DateReceiveFragment.KEY_EVENT_DATA, "事件" + id + "携带的数据");
        openPage(DateReceiveFragment.class, params);
        break;
    case 1:
        params.putBoolean(DateReceiveFragment.KEY_IS_NEED_BACK, true);
        openPageForResult(DateReceiveFragment.class, params, 100);
        break;
    default:
        break;
}

2.4.2、页面切换动画

switch(position) {
    case 0:
        openPage(TestFragment.PAGE_NAME, null, CoreAnim.none);//没有动画
        break;
    case 1:
        openPage(TestFragment.PAGE_NAME, null, CoreAnim.present);//由下到上动画
        break;
    case 2:
        openPage(TestFragment.PAGE_NAME, null, CoreAnim.slide);//从左到右动画
        break;
    case 3:
        openPage(TestFragment.PAGE_NAME, null, CoreAnim.fade);//渐变
        break;
    case 4:
        openPage(TestFragment.PAGE_NAME, null, CoreAnim.zoom);//放大
        break;
    default:
        break;
}

2.5、TitleBar样式自定义

可以设置XPageTitleBarStyle主题样式来自定义标题栏的默认样式。

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/xpage_default_actionbar_color</item>
    <item name="colorPrimaryDark">@color/xpage_default_actionbar_color</item>
    <item name="colorAccent">@color/xpage_default_actionbar_color</item>

    <!--标题栏的背景图片,优先使用背景图片,没有背景图片才使用背景颜色,可选-->
    <item name="xpage_actionbar_background">@null</item>
    <!--标题栏的背景颜色-->
    <item name="xpage_actionbar_color">@color/xpage_default_actionbar_color</item>
    <!--是否支持沉浸式标题栏, 默认false-->
    <item name="xpage_actionbar_immersive">false</item>
    <!--标题栏返回箭头, 默认R.drawable.xpage_ic_navigation_back_white-->
    <item name="xpage_actionbar_navigation_back">@drawable/xpage_ic_navigation_back_white</item>
    <!--标题栏的高度,默认52dp-->
    <item name="xpage_actionbar_height">60dp</item>
    <!--标题栏标题文字的大小,默认18sp-->
    <item name="xpage_actionbar_title_text_size">21sp</item>
    <!--标题栏副标题文字的大小,默认12sp-->
    <item name="xpage_actionbar_sub_text_size">14sp</item>
    <!--标题栏动作文字的大小,默认15sp-->
    <item name="xpage_actionbar_action_text_size">18sp</item>
    <!--标题栏动作图片的padding,默认5dp-->
    <item name="xpage_actionbar_action_padding">6dp</item>
    <!--标题栏两侧文字的padding,默认14dp-->
    <item name="xpage_actionbar_side_text_padding">16dp</item>
    
    <item name="XPageTitleBarStyle">@style/XPageTitleBar.Custom</item>
</style>

<style name="XPageTitleBar.Custom">
    <item name="tb_immersive">false</item>
    <item name="tb_centerGravity">center</item>
</style>

2.6、利用XPage来写程序的Tab主页

详细可参见BottomNavigationViewFragment

就像正常使用ViewPager加载Fragment那样。但是这里需要注意的两点是:

  • 由于使用ViewPager进行加载,而非XPage,因此Fragment的initTitleBar方法需要被覆盖。
@Override
protected TitleBar initTitleBar() {
    //不使用@Page标注的一定要注意覆盖这个方法
    return null;
}
  • 由于为了新开页面不影响Tab主页当前容器的状态,需要在打开新页面的使用设置使用新容器。
PageOption.to(TestFragment.class)
        //新建一个容器,以不影响当前容器
        .setNewActivity(true)
        .open(this);

2.7、复杂Activity界面容器的自定义

详细可参见ComplexActivity

1.自定义页面容器的布局,在布局中一定要包含idfragment_container

<FrameLayout
    android:id="@id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="400dp">
</FrameLayout>

2.在XPageActivity中设置页面容器的自定义布局

@Override
protected View getCustomRootView() {
    binding = ActivityComplexBinding.inflate(getLayoutInflater());
    return binding.getRoot();
}

3.使用changePage方法切换Fragment。

changePage(TestFragment.PAGE_NAME, null, CoreAnim.none);

【注意】在切换Fragment的时候,fragment并不会走onResume和onPause生命周期,建议使用onHiddenChanged代替。

4.使用getPage方法获取指定的Fragment,就可以获取该fragment页面中的数据。

TabAFragment tabAFragment = getPage(TabAFragment.class);
if (tabAFragment != null) {
    ToastUtils.toast(tabAFragment.getData());
} else {
    ToastUtils.toast("页面还未加载!");
}

混淆配置

  • 3.2.0及以上版本,使用的是gson进行序列化的,所以配置如下:
# gson
-keepattributes Signature
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.examples.android.model.** { <fields>; }
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

# xpage
-keep class com.xuexiang.xpage.annotation.** { *; }
-keep class com.xuexiang.xpage.config.** { *; }
  • 3.1.1及以下版本,使用的是fastjson进行序列化的,所以配置如下:
# fastjson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keepattributes Signature

# xpage
-keep class com.xuexiang.xpage.annotation.** { *; }
-keep class com.xuexiang.xpage.config.** { *; }

特别感谢

https://github.com/lizhangqu/CorePage/

如果觉得项目还不错,可以考虑打赏一波

你的打赏是我维护的动力,我将会列出所有打赏人员的清单在下方作为凭证,打赏前请留下打赏项目的备注!

pay.png

联系方式