项目采用组件化架构,如下图所示

首页搭建思路

布局编写

总体布局采用DrawerLayout 实现左侧滑动到菜单区,首页主内存区实现Viewpager和指示器

<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/drawer_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/color_white"><!--存放content主内存区--><RelativeLayoutandroid:id="@+id/content_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/color_white"><RelativeLayoutandroid:id="@+id/title_layout"android:layout_width="match_parent"android:layout_height="45dp"android:layout_marginStart="15dp"android:layout_marginEnd="15dp"><TextViewandroid:id="@+id/toggle_view"android:layout_width="20dp"android:layout_height="20dp"android:layout_alignParentStart="true"android:layout_centerVertical="true"android:background="@mipmap/category" /><TextViewandroid:id="@+id/search_view"android:layout_width="20dp"android:layout_height="20dp"android:layout_alignParentEnd="true"android:layout_centerVertical="true"android:background="@mipmap/b_p" /><net.lucode.hackware.magicindicator.MagicIndicatorandroid:id="@+id/magic_indicator"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_centerVertical="true"android:layout_marginStart="42dp"android:layout_marginEnd="42dp"android:layout_toStartOf="@id/search_view"android:layout_toEndOf="@id/toggle_view" /></RelativeLayout><com.imooc.lib_audio.mediaplayer.view.BottomMusicViewandroid:id="@+id/bottom_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true" /><androidx.viewpager.widget.ViewPagerandroid:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/bottom_view"android:layout_below="@id/title_layout" /></RelativeLayout><!-- 存放侧滑菜单区--><RelativeLayoutandroid:id="@+id/left_drawer_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="start"android:layout_marginEnd="25dp"android:background="@color/color_white"><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_above="@id/divider"android:scrollbars="none"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/avatr_view"android:layout_width="150dp"android:layout_height="150dp"android:layout_centerHorizontal="true"android:layout_marginTop="20dp"android:visibility="gone" /><LinearLayoutandroid:id="@+id/unloggin_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:gravity="center"android:text="@string/home_login_tip"android:textColor="@color/color_333333"android:textSize="13sp" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="2dp"android:gravity="center"android:text="@string/home_login_tip_2"android:textColor="@color/color_333333"android:textSize="13sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="20dp"android:background="@drawable/bg_home_login"android:paddingStart="40dp"android:paddingTop="5dp"android:paddingEnd="40dp"android:paddingBottom="5dp"android:text="@string/home_login"android:textColor="@color/color_333333"android:textSize="15sp" /></LinearLayout></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="35dp"android:orientation="horizontal"android:paddingStart="30dp"android:paddingEnd="30dp"><com.imooc.lib_commin_ui.VerticalItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"app:icon="@mipmap/abi"app:iconHeight="35dp"app:iconWidth="35dp"app:infoText="我的消息"app:infoTextColor="@color/color_333333"app:infoTextMarginTop="5dp"app:infoTextSize="11sp"app:tipBg="@drawable/bg_home_tip"app:tipPaddingRight="2dp"app:tipPaddingTop="2dp"app:tipText="1"app:tipTextColor="@color/color_white"app:tipTextSize="11sp" /><com.imooc.lib_commin_ui.VerticalItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"app:icon="@mipmap/abj"app:iconHeight="35dp"app:iconWidth="35dp"app:infoText="我的好友"app:infoTextColor="@color/color_333333"app:infoTextMarginTop="5dp"app:infoTextSize="11sp"app:tipBg="@drawable/bg_home_tip"app:tipPaddingRight="2dp"app:tipPaddingTop="2dp"app:tipText="1"app:tipTextColor="@color/color_white"app:tipTextSize="11sp" /><com.imooc.lib_commin_ui.VerticalItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"app:icon="@mipmap/abk"app:iconHeight="35dp"app:iconWidth="35dp"app:infoText="个性换肤"app:infoTextColor="@color/color_333333"app:infoTextMarginTop="5dp"app:infoTextSize="11sp"app:tipBg="@drawable/bg_home_tip"app:tipPaddingRight="2dp"app:tipPaddingTop="2dp"app:tipText="1"app:tipTextColor="@color/color_white"app:tipTextSize="11sp" /><com.imooc.lib_commin_ui.VerticalItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"app:icon="@mipmap/abi"app:iconHeight="35dp"app:iconWidth="35dp"app:infoText="听歌识曲"app:infoTextColor="@color/color_333333"app:infoTextMarginTop="5dp"app:infoTextSize="11sp"app:tipBg="@drawable/bg_home_tip"app:tipPaddingRight="2dp"app:tipPaddingTop="2dp"app:tipText="1"app:tipTextColor="@color/color_white"app:tipTextSize="11sp" /></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:layout_margin="20dp"android:background="#dddddd" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/anc"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:rightText="林志颖北京"app:tileText="演出" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/and"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:rightText="JBL耳机78元"app:tileText="商城" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/ane"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="附近的人" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/anf"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="口袋铃声" /><Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:layout_margin="20dp"android:background="#dddddd" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/ang"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="定时停止播放" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:id="@+id/home_qrcode"android:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/anh"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="扫一扫" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:id="@+id/home_music"android:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/ani"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="音乐闹钟" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:id="@+id/online_music_view"android:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/anj"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="在线听歌免流量" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/ank"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="游戏推荐" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/anl"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="优惠卷" /><com.imooc.lib_commin_ui.HornizeItemViewandroid:id="@+id/check_update_view"android:layout_width="match_parent"android:layout_height="wrap_content"app:hIcon="@mipmap/anm"app:hTipVisiblity="false"app:paddingLeft="20dp"app:paddingRight="20dp"app:tileText="检查更新" /></LinearLayout></ScrollView><Viewandroid:id="@+id/divider"android:layout_width="match_parent"android:layout_height="0.5dp"android:layout_alignTop="@id/operator_view"android:background="#dddddd" /><LinearLayoutandroid:id="@+id/operator_view"android:layout_width="match_parent"android:layout_height="52dp"android:layout_alignParentBottom="true"android:orientation="horizontal"><LinearLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="3"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:layout_width="20dp"android:layout_height="20dp"android:src="@mipmap/baz" /><Viewandroid:layout_width="6dp"android:layout_height="match_parent" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="夜间模式"android:textColor="@color/color_333333"android:textSize="15sp" /></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:layout_width="20dp"android:layout_height="20dp"android:src="@mipmap/bb1" /><Viewandroid:layout_width="6dp"android:layout_height="match_parent" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="设置"android:textColor="@color/color_333333"android:textSize="15sp" /></LinearLayout><LinearLayoutandroid:id="@+id/exit_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:layout_width="20dp"android:layout_height="20dp"android:src="@mipmap/baq" /><Viewandroid:layout_width="6dp"android:layout_height="match_parent" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="退出"android:textColor="@color/color_333333"android:textSize="15sp" /></LinearLayout></LinearLayout></RelativeLayout>
</androidx.drawerlayout.widget.DrawerLayout>

指示器初始化

通过枚举封装首页卡片类型,分为我的、发现、朋友、视频,将指示器和viewpager绑定

public enum CHANNEL {MY("我的", 0x01),DISCORY("发现", 0x02),FRIEND("朋友", 0x03),VIDEO("视频", 0x04);//所有类型标识public static final int MINE_ID = 0x01;public static final int DISCORY_ID = 0x02;public static final int FRIEND_ID = 0x03;public static final int VIDEO_ID = 0x04;private final String key;private final int value;CHANNEL(String key, int value) {this.key = key;this.value = value;}public int getValue() {return value;}public String getKey() {return key;}
}
    private void initMagicIndicator() {MagicIndicator magicIndicator = findViewById(R.id.magic_indicator);magicIndicator.setBackgroundColor(Color.WHITE);CommonNavigator commonNavigator = new CommonNavigator(this);commonNavigator.setAdjustMode(true);commonNavigator.setAdapter(new CommonNavigatorAdapter() {@Overridepublic int getCount() {return CHANNELS == null ? 0 : CHANNELS.length;}@Overridepublic IPagerTitleView getTitleView(Context context, final int index) {SimplePagerTitleView simplePagerTitleView = new ScaleTransitionPagerTitleView(context);simplePagerTitleView.setText(CHANNELS[index].getKey());simplePagerTitleView.setTextSize(19);simplePagerTitleView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));simplePagerTitleView.setNormalColor(Color.parseColor("#999999"));simplePagerTitleView.setSelectedColor(Color.parseColor("#333333"));simplePagerTitleView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mViewPager.setCurrentItem(index);}});return simplePagerTitleView;}@Overridepublic IPagerIndicator getIndicator(Context context) {return null;}@Overridepublic float getTitleWeight(Context context, int index) {return 1.0f;}});magicIndicator.setNavigator(commonNavigator);ViewPagerHelper.bind(magicIndicator, mViewPager);}

viewpager初始化

不使用传入fragment的list,防止卡顿,每次点击的时候再创建一个newInstance

public class HomePagerAdapter extends FragmentPagerAdapter {private CHANNEL[] mList;public HomePagerAdapter(FragmentManager fm, CHANNEL[] datas) {super(fm);mList = datas;}//这种方式,避免一次性创建所有的framgent@Overridepublic Fragment getItem(int position) {int type = mList[position].getValue();switch (type) {case CHANNEL.MINE_ID:return MineFragment.newInstance();case CHANNEL.DISCORY_ID:return DiscoryFragment.newInstance();case CHANNEL.FRIEND_ID:return FriendFragment.newInstance();case CHANNEL.VIDEO_ID:return VideoFragment.Companion.newInstance();}return null;}@Overridepublic int getCount() {return mList == null ? 0 : mList.length;}
}

沉浸式效果开发

单纯修改配置文件不一定能实现沉浸效果,还需要手动使用代码实现

<?xml version="1.0" encoding="utf-8"?>
<resources><style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"><item name="android:windowTranslucentStatus">false</item><!--<item name="android:windowTranslucentNavigation">true</item>--><!--&lt;!&ndash;Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色&ndash;&gt;--><!--&lt;!&ndash; 可以修改状态栏的颜色 --><item name="android:statusBarColor">@android:color/transparent</item><item name="android:navigationBarColor">@android:color/white</item><item name="android:fitsSystemWindows">true</item><!--允许activity的transition转场动画--><item name="android:windowActivityTransitions">true</item></style>
</resources>

在基础ui组件lib_common_ui下创建工具类和BaseActivity

public class StatusBarUtil {/*** 修改状态栏为全透明*/public static void transparencyBar(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Window window = activity.getWindow();window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(Color.TRANSPARENT);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {Window window = activity.getWindow();window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}}/*** 状态栏亮色模式,设置状态栏黑色文字、图标,* 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android** @return 1:MIUUI 2:Flyme 3:android6.0*/public static void statusBarLightMode(Activity activity) {int result = 0;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {if (miuiSetStatusBarLightMode(activity, true)) {result = 1;} else if (flymeSetStatusBarLightMode(activity.getWindow(), true)) {result = 2;} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);result = 3;}}}/*** 已知系统类型时,设置状态栏黑色文字、图标。* 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android** @param type 1:MIUUI 2:Flyme 3:android6.0*/public static void statusBarLightMode(Activity activity, int type) {if (type == 1) {miuiSetStatusBarLightMode(activity, true);} else if (type == 2) {flymeSetStatusBarLightMode(activity.getWindow(), true);} else if (type == 3) {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}/*** 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标*/public static void StatusBarDarkMode(Activity activity, int type) {if (type == 1) {miuiSetStatusBarLightMode(activity, false);} else if (type == 2) {flymeSetStatusBarLightMode(activity.getWindow(), false);} else if (type == 3) {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);}}/*** 设置状态栏图标为深色和魅族特定的文字风格* 可以用来判断是否为Flyme用户** @param window 需要设置的窗口* @param dark 是否把状态栏文字及图标颜色设置为深色* @return boolean 成功执行返回true*/public static boolean flymeSetStatusBarLightMode(Window window, boolean dark) {boolean result = false;if (window != null) {try {WindowManager.LayoutParams lp = window.getAttributes();Field darkFlag =WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");darkFlag.setAccessible(true);meizuFlags.setAccessible(true);int bit = darkFlag.getInt(null);int value = meizuFlags.getInt(lp);if (dark) {value |= bit;} else {value &= ~bit;}meizuFlags.setInt(lp, value);window.setAttributes(lp);result = true;} catch (Exception e) {}}return result;}/*** 需要MIUIV6以上** @param dark 是否把状态栏文字及图标颜色设置为深色* @return boolean 成功执行返回true*/public static boolean miuiSetStatusBarLightMode(Activity activity, boolean dark) {boolean result = false;Window window = activity.getWindow();if (window != null) {Class clazz = window.getClass();try {int darkModeFlag;Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");darkModeFlag = field.getInt(layoutParams);//noinspection uncheckedMethod extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);if (dark) {//状态栏透明且黑色字体extraFlagField.invoke(window, darkModeFlag, darkModeFlag);} else {//清除黑色字体extraFlagField.invoke(window, 0, darkModeFlag);}result = true;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上if (dark) {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);} else {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);}}} catch (Exception e) {}}return result;}//获取屏幕虚拟键高度public static int getVirtualBarHeight(Context context) {int vh = 0;WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display display = windowManager.getDefaultDisplay();DisplayMetrics dm = new DisplayMetrics();try {@SuppressWarnings("rawtypes") Class c = Class.forName("android.view.Display");@SuppressWarnings("unchecked") Method method =c.getMethod("getRealMetrics", DisplayMetrics.class);method.invoke(display, dm);vh = dm.heightPixels - display.getHeight();} catch (Exception e) {e.printStackTrace();}return vh;}public static int getStatusBarHeight(Context context) {int height = 0;try {Class c = Class.forName("com.android.internal.R$dimen");Field f = c.getField("status_bar_height");int id = (int) f.get(null);height = context.getResources().getDimensionPixelSize(id);} catch (Exception e) {}return height;}public static int dip2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}public static int px2dip(Context context, float pxValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (pxValue / scale + 0.5f);}/** 获取手机的密度 */public static float getDensity(Context context) {DisplayMetrics dm = context.getResources().getDisplayMetrics();return dm.density;}
}

创建BaseActivity,使用工具类实现沉浸效果:

public class BaseActivity extends FragmentActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);StatusBarUtil.statusBarLightMode(this);}
}

最终实现效果:

音乐APP首页框架搭建相关推荐

  1. android真实项目教程(一)——App应用框架搭建_by_CJJ

    大家好,我是CJJ,学android半年了,仍然是菜虫一只......为了进步,想把自己知道的知识和初学者分享,也希望路过的大神能给些意见....呵呵......开始今天的教程吧,晕,不敢说教程了 , ...

  2. Android App软件框架搭建

    1. App软件框架搭建 1.0软件基本架构 1.1创建MainActivity并设置布局文件 布局文件如下: <?xml version="1.0" encoding=&q ...

  3. APP自动化测试框架搭建(五)--Python+Appium+pytest-html

    第一章 APP自动化环境搭建(Mac版) 第二章 APP自动化环境搭建(Windows版) 第三章 adb命令 第四章 元素定位.元素操作 第五章 APP自动化测试框架搭建 Python+Appium ...

  4. APP自动化测试框架搭建(六)--uiautomator2、web-editor基础操作

    第一章 APP自动化环境搭建(Mac版) 第二章 APP自动化环境搭建(Windows版) 第三章 adb命令 第四章 元素定位.元素操作 第五章 APP自动化测试框架搭建 Python+Appium ...

  5. APP自动化测试框架搭建(八)--ATX Server2多设备集群环境搭建

    第一章 APP自动化环境搭建(Mac版) 第二章 APP自动化环境搭建(Windows版) 第三章 adb命令 第四章 元素定位.元素操作 第五章 APP自动化测试框架搭建 Python+Appium ...

  6. 【App自动化框架搭建流程及其思路】

    App自动化框架搭建流程 之前公司我所在的业务是关于sdk的一些业务,为了缓解我们sdk组的功能测试大量重复性业务.我搭建了一套App自动化框架,现已投入日常的使用.这篇文章简单的介绍下我这个App自 ...

  7. 玩安卓从 0 到 1 之首页框架搭建

    前言 这篇文章是这个系列的第三篇文章了,前两篇文章分别是玩安卓从 0 到 1 之总体概览和玩安卓从 0 到 1 之项目首页. 一开始想的是一篇文章搞定,从项目的搭建到完成把所有的知识点写一遍,努力不做 ...

  8. APP基本框架搭建丨一键换肤 - Android-skin-support

    介绍 Android-skin-support: 一款 Android 换肤框架, 极低的学习成本, 极好的用户体验. 只需要一行代码, 就可以实现换肤, 你值得拥有!!! SkinCompatMan ...

  9. App基本框架搭建丨日志管理 - KLog

    项目介绍 这是一个Android专用的LogCat工具,主要功能为打印行号.函数调用.Json解析.XML解析.点击跳转.Log信息保存等功能 Android LogCat 工具类,目前功能: 支持显 ...

  10. 从0开始写一个基于Flutter的开源中国客户端(5)——App整体布局框架搭建

    上一篇中我记录了Flutter中常用的一些布局,本篇开始开发基于Flutter的开源中国客户端了.在本篇博客中,要实现的是一个App的整体框架,包括页面底部的Tab导航菜单.页面的侧滑菜单以及跳转到新 ...

最新文章

  1. [高中作文赏析]假如真的有时光隧道
  2. linux shell unlink,linux shell中,unlink和rm命令有什么区别
  3. 使用GitHub Pages搭建博客
  4. sicp 4.2.1两题
  5. Android 安全专项-Xposed 劫持用户名密码实践
  6. 后端开发应该掌握的 Redis 基础
  7. wampserver服务器无法启动(图标颜色不对)
  8. Centos6.4下安装mysql5.6.10
  9. 不知风险 何谈 5G?
  10. c语言51单片机rrc,MCS-51单片机汇编指令详解
  11. iOS voip电话和sip软电话 --网络电话
  12. 《领域驱动设计 DDD》核心知识梳理笔记
  13. 动态规划初级篇(上)
  14. ubuntu安装使用redis并设置开机启动
  15. TestNG 参数化测试
  16. 四则运算之结对作业报告
  17. 拜托,在学校开拖拉机很酷的!
  18. Android 自定义底部上拉控件的实现
  19. 数据分析案例-数据科学相关岗位薪资可视化分析
  20. fedora安装fcitx

热门文章

  1. wirehark数据分析与取证attack.pcap
  2. 【打开CMD的方法】
  3. numpy_subtract函数
  4. 正北坐标系和车辆坐标系下的heading转换
  5. 西安千锋培训python
  6. 在哪里写博客比较好?不同写作平台的横向对比
  7. Python的scrapy之爬取6毛小说网
  8. “标注神器”——Zeplin使用教程(Ps版)
  9. 省市名_code_拼音
  10. 计算机网络:网络传输介质