Android Navigation + Fragment 制作APP主页面导航(步骤 + 源码)

简介: Android Navigation + Fragment 制作APP主页面导航(步骤 + 源码)

Navigation + Fragment制作APP主页面


前言


 我相信你肯定见过这样的App主页面,底部或者顶部有多个按钮,点击之后会切换当前的页面,滑动当前页面也会切换底部按钮,这里我用几个App的主页面来说明一下吧

淘宝

20201208164210347.png


微博


20201208164258880.png


CSDN App


20201208164333992.png


支付宝


20201208164407243.png


可以说绝大部分App都是这种主页面布局模式,当然还有很多,在这里举列子是让你有一个概念而已。


那么来看看本文中实现的效果是怎么样的。如果不满意,我想也就不浪费你的时间了。


20201209162955432.gif


正文


 从上面的一些APP主页面,在之前这种页面是通过什么来做的呢?这里有好几种组合:


① Activity + Fragment + TabLayout + ViewPager。


② Activity + Fragment + RadioGroup(RadioButton) + ViewPager。


相信你在很多的博客上或者自己的项目上看过或者使用过。而现在可以通过另一个更简洁的方式,那就是Activity+ Navigation + Fragment。虽然你看着只是少了一个控件而已,但实际上,大部分的工作都是由Navigation (导航)来完成。


说了这么多也该正式操作了,既然是写博客,自然要详细一些了,那么我们就从创建AS项目开始吧。这应该够详细了吧,首先创建一个名为AppHomeNavigation的项目。如下图所示,包名我就缩减了一下。


20201208165426726.png


创建好之后如下图所示:

2020120816564949.png


从这个图来看,项目本身没有任何问题,为了保险起见,建议先运行一下。


1. 添加依赖


 Navigation 是JetPack中的组件,感兴趣可以去查看Google JetPack官方文档。而如果你想单独查看的Navigation 内容,可以点击Navigation 文档。


打开你的app下的build.gradle。在dependencies闭包中添加如下依赖:


  def nav_version = "2.3.2"
    // navigation依赖 ui 和 fragment
    implementation "androidx.navigation:navigation-fragment:$nav_version"
    implementation "androidx.navigation:navigation-ui:$nav_version"


添加位置如下图所示:


20201208171655589.png


添加好之后,点击Sync进行项目同步,同步时会自动下载这些依赖库并配置到你的项目中。


添加完了依赖,就得先来简单介绍一下这个Navigation了,Navigation分为三大件:导航图、NavHost、NavController。


为了方便我介绍下面的三个概念,这里假设有A、B、C三个Fragment。


现在要从A切换到B


导航图:读取这个切换目标及路径

NavHost:包含A、B、C的容器,用于显示Fragment。

NavController:在得知切换目标时,控制NavHost去显示B这个Fragment。


这么一说,你是否有一些理解了呢?


2. 添加导航图


鼠标右键点击res → New → Android Resource File


20201208180029975.png


然后会弹出一个窗体,在这个窗体里面设置文件名称,并选择文件类型,然后点击OK。


20201208180355312.png


然后查看这个nav_graph.xml,你会发现有报错


20201208180640128.png


不过先不用担心,因为这个里面是用来指向Fragment的,但是现在没有,那就创建。

然后先在com.llw.navigation下新建一个fragment包。

然后建一个Fragment类,这里命名我就用ABCDE来命名了,实际开发中是肯定不能这样的。


20201208181104665.png


然后在layout新建一个布局fragment_a.xml


20201208181316204.png


然后修改一下这个布局


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="A Fragment"
        android:textColor="#000"
        android:textSize="24sp" />
</LinearLayout>


布局有了,然后进入到AFragment中绑定这个布局的id。


public class AFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_a, container, false);
    }
}


那么这个AFragment就弄好了,同样按照上面的步骤创建BCDE的Fragment,这个重复的步骤我就不写了,因为有注水的涉嫌。


注意之前fragment_a.xml中我放了一个TextView用来表示这个是A,那么其他的xml中也要放置对应的BCDE,这样你切换的时候才能看到区别。


好了,下面可以打开这个nav_graph.xml进行Fragment的添加,在navigation标签下增加对AFragment的添加。


  <!--AFragment-->
    <fragment
        android:id="@+id/afragment"
        android:name="com.llw.navigation.fragment.AFragment"
        android:label="afragment"
        tools:layout="@layout/fragment_a" />


上面的也很简单,id表示它在导航图的标识,name指明这个Fragment的路径,包名+类名。label就是标签而已。layout就是绑定这个Fragment对应的布局。


这里你肯定回想,刚才不是在AFragment的onCreateView方法的返回中指明这这个布局吗?


那么这里又添加是为什么,因为你如果在导航图中指明了某一个Fragment的布局,那么在代码中就可以不用指明,也可以两者都指明,但至少要有一个地方指明,所以我这样写是可以的。为了让看的人更了解而已,虽然是多此一举。


那么这个nav_graph.xml的其他的Fragment也要添加,如下所示

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph">
    <!--AFragment-->
    <fragment
        android:id="@+id/afragment"
        android:name="com.llw.navigation.fragment.AFragment"
        android:label="afragment"
        tools:layout="@layout/fragment_a" />
    <!--BFragment-->
    <fragment
        android:id="@+id/bfragment"
        android:name="com.llw.navigation.fragment.BFragment"
        android:label="bfragment"
        tools:layout="@layout/fragment_b" />
    <!--CFragment-->
    <fragment
        android:id="@+id/cfragment"
        android:name="com.llw.navigation.fragment.CFragment"
        android:label="cfragment"
        tools:layout="@layout/fragment_c" />
    <!--DFragment-->
    <fragment
        android:id="@+id/dfragment"
        android:name="com.llw.navigation.fragment.DFragment"
        android:label="dfragment"
        tools:layout="@layout/fragment_d" />
    <!--EFragment-->
    <fragment
        android:id="@+id/efragment"
        android:name="com.llw.navigation.fragment.EFragment"
        android:label="efragment"
        tools:layout="@layout/fragment_e" />
</navigation>


然后你会发现还报错,那么你可以现在navigation标签中添加


tools:ignore="UnusedNavigation"

20201209094029241.png


它就不报错了,这句话的意思是未使用导航的许可。因为我现在还没有使用这个nav_graph.xml所以要加上这一句话告诉AS,让它放心。等我们真正去使用时,是没有影响的,去不去掉都行。


3. 添加NavHost


这个在上面是介绍过的,它是用来装载和显示Fragment的,都知道Fragment是要依附在Activity上的,那么很明显这个NavHost也是要放在Activity中,那么下面打开activity_main.xml。修改代码如下:


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!--NavHost-->
    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>


可能这里你会比较陌生,这里的id,等下要在MainActivity中指明的,这里的name指明的是androidx.navigation.fragment.NavHostFragment,这个属性就表明这个fragment指明的就是NavHost,然后它还要添加需要显示的子Fragment,那么就通过navGraph来绑定这个导航图,之前导航图里面不是就有五个Fragment吗?所以这样NavHost的任务就完成了。


但是这时候又有一个问题,那就是我的这个NavHost初始显示哪一个Fragment,这一点Google的人也想到了,可以在导航图中指明。


打开nav_graph.xml。通过startDestination来指明启动Activity时显示的第一个Fragment。


app:startDestination="@id/afragment"

20201209095932920.png


这里我指明了AFragment。那么值钱说到的三大件,就还差一个NavController。这个是用来控制NavHost显示Fragment,虽然我刚才在导航图nav_graph.xml中指明了第一个要显示的Fragment,但是它还缺少这个显示的动机,而这个动机由NavController来提供。


4. NavController控制显示Fragment


进入到MainActivity,在onCreate添加一句代码:


    //获取navController
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);


这时候你运行代码,然后你就会发现,显示了AFragment。

20201209101915594.png


惊不惊喜意不意外?明明这个NavController还什么都没有做的,为什么就可以显示了呢?实际上它已经在工作了,只是你没有注意而已。


Navigation.findNavController(this, R.id.nav_host_fragment);


通过这一行代码这个工作开关就已经打开了,打开中读取导航图中第一个要显示Fragment,然后显示在NavHostFragment中。

5. Fragment之间跳转并传值


平时在实际的开发中常常会从一个Fragment跳转到另一个Fragment,并且带一些参数过去,之前这些跳转都是比较麻烦的,需要自己去写一些业务逻辑,而且还很容易出问题,让人谈之色变。但是在Navigation中,这个状况得到了很大的改善。


那么具体来看一下是怎么做的,比如我现在从AFragment跳转到BFragment。


下面就是见证骚操作的时候了。打开nav_graph.xml,修改AFragment。


  <!--AFragment-->
    <fragment
        android:id="@+id/afragment"
        android:name="com.llw.navigation.fragment.AFragment"
        android:label="afragment"
        tools:layout="@layout/fragment_a">
        <!--添加动作-->
        <action
            android:id="@+id/action_afragment_to_bfragment"
            app:destination="@id/bfragment"
            app:enterAnim="@anim/nav_default_enter_anim"
            app:exitAnim="@anim/nav_default_exit_anim" />
    </fragment>


这里又多了一个新的action标签,表示动作,id的命名要规范,从这个命名来看就知道要从A跳转到B。然后就是destination属性,它指明一个跳转到的Fragment。enterAnim表示进入BFragment的动画,exitAnim表示退出BFragment的动画,这些都是Navgation中自带的。


现在动作写好了,那么下面就需要一个地方来触发这个动作,可以写一个简单的按钮来触发。


在fragment_a.xml中修改布局如下:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="A Fragment"
        android:textColor="#000"
        android:textSize="24sp" />
    <Button
        android:id="@+id/jumpBFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="跳转到 BFragment"
        android:textAllCaps="false"
        android:textSize="16sp" />
</LinearLayout>


然后进入到AFragment中,绑定id,增加点击事件。代码如下:


package com.llw.navigation.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import com.llw.navigation.R;
public class AFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_a, container, false);
    }
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button jumpBFragment = view.findViewById(R.id.jumpBFragment);
        jumpBFragment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Navigation.findNavController(getView())
                        //导航
                        .navigate(R.id.action_afragment_to_bfragment);
            }
        });
    }
}


这里唯一不好理解的就是navigate,表示导航的意思,这里面我传入了刚才定义在nav_graph.xml中的action的id。就表示这个导航将要执行这个actiion,那么它就会跳转到BFragment。运行一下


20201209104847814.gif


很明显,跳过去了,不过感觉还少了点什么,因为平常Fragment之间跳转时都会传递参数过去,那么这个也要传参数,而Navigation也提供了这个功能,可以通过Bundle进行传参。


所以只要简单的修改这个点击的方法就可以了。


    jumpBFragment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle bundle = new Bundle();
                bundle.putString("content","How are you?");
                Navigation.findNavController(getView())
                        //导航
                        .navigate(R.id.action_afragment_to_bfragment,bundle);
            }
        });


这种Bundle传递参数我相信都不会陌生,那么在BFragment怎么去接收呢?


打开BFragment,修改代码如下:


package com.llw.navigation.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.llw.navigation.R;
public class BFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        String content = getArguments().getString("content");
        Toast.makeText(getActivity(),content,Toast.LENGTH_SHORT).show();
        return inflater.inflate(R.layout.fragment_b, container, false);
    }
}


这里通过


getArguments().getString("content");


来获取刚才放入Bundle里面的值,你以前可能没有见过这个方法,但是你只要把getArguments当成是getBundle()就好理解了,因为它实际上就是返回了一个Bundle。


20201209105909491.png


然后看一下运行的效果吧。


20201209110142851.gif


可以看到是不是已经传递了传输过来,简单吧。


现在你会发现跳转是没有问题,但是回退呢?怎么回去呢?如果你这个时候在BFragment点击系统的返回键,你会发现直接退出当前应用了,因为这个时候Fragment还是属于MainActivity,那么它使用的就是Activity的返回栈,可当前只有一个Activity,所以它就退无可退,只能关闭应用,回到桌面了。为了解决这个问题,Navigation也提供了一个属性,在activity_main.xml中的的fragment中增加一个属性


app:defaultNavHost="true"

2020120911085617.png


然后这个时候你再试一下,从A到B,然后点击系统返回键,就会返回到A,然后再点一下返回键就会退出当前应用。


神不神奇?app:defaultNavHost="true"表示这个回退栈由NavController来管理,当这个退无可退时才会调用Activity的回退栈。默认就是false,可以不加。


6. 添加底部导航


鼠标右键点击res → New → Android Resource File,然后选择Menu


20201209145844725.png


之后打开menu.xml去添加子项。


<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/afragment"
        android:icon="@mipmap/ic_home"
        android:title="首页" />
    <item
        android:id="@+id/bfragment"
        android:icon="@mipmap/ic_category"
        android:title="类别" />
    <item
        android:id="@+id/cfragment"
        android:icon="@mipmap/ic_find"
        android:title="发现" />
    <item
        android:id="@+id/dfragment"
        android:icon="@mipmap/ic_msg"
        android:title="消息" />
    <item
        android:id="@+id/efragment"
        android:icon="@mipmap/ic_mine"
        android:title="我的" />
</menu>


之前我是有5个Fragment,那么这里添加5个item,并且item的id要和之前导航图的fragment的id保持一致。这里面的图标其实很容易搞到。


ic_home.png


20201209151106277.png


ic_category.png


20201209151106268.png


ic_find.png


20201209151106273.png


ic_msg.png


20201209151106280.png


ic_mine.png


现在menu创建好了,那么可以在activity_main.xml中进行添加了。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!--NavHost-->
    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottom_navigation"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />
    <!--底部导航-->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_alignParentBottom="true"
        android:background="#FFF"
        app:menu="@menu/menu" />
</RelativeLayout>


通过menu来指定导航栏的菜单,这样就把刚才的item都添加进去了


现在你通过预览已经可以看到这个底部导航栏了,不是吗?不过保险起见,我还是运行一手。


20201209152347489.gif


可以看到,底部的导航栏已经出来了,而且还可以点击,点击之后还有动画效果,并且图标和文字的颜色还有变化,因为实际上我只是放了灰色图标而已。那么这些工作就都是BottomNavigationView帮我们完成的,的确是省了不少事情,当然这个动画效果和点击之后的颜色都是可以让开发者自行改的。这是Google要做的UI统一,通过material来实现一些效果和动画。


7. 底部导航栏控制Fragment切换


在上面已经添加了底部导航栏,但是这个导航栏还没有和NavHost绑定起来,所以自然就无法在切换底部导航的同时,改变NavHost中的Fragment。进入到MainActivity。


public class MainActivity extends AppCompatActivity {
    BottomNavigationView bottomNavigation;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bottomNavigation = findViewById(R.id.bottom_navigation);
        //获取navController
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        //通过setupWithNavController将底部导航和导航控制器进行绑定
        NavigationUI.setupWithNavController(bottomNavigation,navController);
    }
}


像这样绑定之后,你现在点击底部导航之后,NavController就会控制NavHost去显示相应的Fragment。


不过在运行之前把BFragment中接收参数并且弹Toast的代码删掉,否则切换的时候拿不到这个参数,就会ANR。


运行看看吧。


20201209154604112.gif


下面来改一下切换后的图标颜色和文字颜色吧。


右键点击drawable然后新建一个menu_item_selected.xml。


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#888888" android:state_checked="false" />
    <item android:color="#1296DB" android:state_checked="true" />
</selector>


意思很简单,就是设置未选中和选中时的颜色。进入activity_mian.xml修改BottomNavigationView


  <!--底部导航-->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_alignParentBottom="true"
        android:background="#FFF"
        app:itemIconTint="@drawable/menu_item_selected"
        app:itemTextColor="@drawable/menu_item_selected"
        app:labelVisibilityMode="labeled"
        app:menu="@menu/menu" />


    app:itemIconTint="@drawable/menu_item_selected"
        app:itemTextColor="@drawable/menu_item_selected"


可以看到itemIconTint和itemTextColor分别表示图标和文字,这里传入刚才传入的颜色样式。

app:labelVisibilityMode="labeled"


这个labeled表示一直显示标签文字,它还有三种模式,分别是auto、selected、unlabeled。


auto表示自动,默认就是这种模式,selected和auto差不多,unlabeled表示一直不显示标签文字。可以自行去尝试。

8. 运行效果图和源码


那么下面再运行一下吧。


20201209162955432.gif


可以看到现在有很多APP都是这样的效果。那么本篇文章要做的事情就做完了。


总结


 其实我这里没有做通过滑动Fragment来切换BottomNavigationView。如果要做的话,就要加ViewPager来控制Fragment,而不是NavHost来控制了,那样就脱离了这个文章的目的了。而且使用ViewPager的话就是相当于你把BottomNavigationView替换RadioButton或者TabLayout来使用,这种方式也有很多,我就过多的说明了,上高水长,后会有期~


相关文章
|
7月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1245 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
535 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
12月前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
238 0
|
7月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
343 0
|
10月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
1198 4
|
11月前
《仿盒马》app开发技术分享-- 个人中心页面(19)
上一节我们实现了分类页面的所有联动效果,这一节我们要开始完成一个新的页面,这个页面是我们主界面的第四个板块,就是个人中心页面。在这个模块,我们可以显示一些用户信息,以及用户相关的各类功能的入口
163 4
|
12月前
|
人工智能 前端开发 JavaScript
打造了一个未来感十足的图书管理 App 个人页面
打造了一个未来感十足的图书管理 App 个人页面
343 25
|
数据采集 JSON 网络安全
移动端数据抓取:Android App的TLS流量解密方案
本文介绍了一种通过TLS流量解密技术抓取知乎App热榜数据的方法。利用Charles Proxy解密HTTPS流量,分析App与服务器通信内容;结合Python Requests库模拟请求,配置特定请求头以绕过反爬机制。同时使用代理IP隐藏真实IP地址,确保抓取稳定。最终成功提取热榜标题、内容简介、链接等信息,为分析热点话题和用户趋势提供数据支持。此方法也可应用于其他Android App的数据采集,但需注意选择可靠的代理服务。
547 11
移动端数据抓取:Android App的TLS流量解密方案
|
12月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
674 2
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。

热门文章

最新文章