打造自己的 APP「冰与火百科」(四):WebView 交互、夜间模式

来源:互联网 发布:ps淘宝美工教程视频 编辑:程序博客网 时间:2024/06/01 17:50

给大家介绍一下简单的 WebView 交互和夜间模式在「冰与火百科」中的实现。

WebView 交互

在详情页面我是用 WebView 展示的,我想实现的交互是,点击 WebView 的内容跳转另一个页面。实现过程是,让 HTML 代码调用 JavaScript 代码,再让 JavaScript 代码调用 Android 的代码,下面看看如何实现。

HTML

先看 HTML 代码,假如在文本内容里有一个可以跳转的「凯特琳·徒利」,让他去调用 skip.js 的代码,指定 CatelynTully() 方法:

<body>  <a href="javascript:void(0)" onclick="CatelynTully()">凯特琳·徒利</a>  <script type="text/javascript" src="skip.js"></script></body>

JavaScript

这个 skip.js 文件我是放在客户端的,放在 assets 目录下,代码如下:

function CatelynTully(){    javascript:Android.goDetail('Catelyn_Tully');}

意思就是去调用 Android 的 goDetail(String id) 方法。

Android

在客户端添加 goDetail 方法,我把 JavaScript 和 Java 交互的代码写在一个类里,记得给方法加上 @JavascriptInterface 注解:

public class Js2Java {    private Context mContext;    public Js2Java(Context context) {        this.mContext = context;    }    @JavascriptInterface    public void goDetail(String id) {        // 根据 id 跳转页面    }}

来到显示 WebView 的页面,添加以下代码让 WebView 支持 JavaScript:

webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(new Js2Java(this), "Android");

使用 loadDataWithBaseURL 来展示数据:

binding.webView.loadDataWithBaseURL("file:///android_asset/", htmlData, "text/html", "utf-8", null);

这样就完成了一个简单的 JavaScript 和 Android 的交互,效果如下:

夜间模式

关于夜间模式的实现,主要是参考了 D_clock爱吃葱花 大神的这篇文章,简单说一下实现过程如下:

  1. 在 styles 中添加「DayTheme」和「NightTheme」两个主题;
  2. 在布局文件中使用类似 android:background=”?attr/colorBackground” 来设置颜色,使其跟随当前主题颜色;
  3. 编写 DayNightHelper,利用 SharePreferences 保存、获取当前模式;
  4. 在页面 setContentView 之前,判断当前模式,并通过 setTheme 设置当前模式;
  5. 将屏幕内容转为 Bitmap,对其执行一个渐隐动画,实现切换时渐变的效果;
  6. 监听模式切换,通过 TypedValue 和 Theme.resolveAttribute 在代码中获取 Theme 中的颜色,重新设置控件的颜色。

更详细的内容可以查看原文,下面再补充几个控件的颜色设置方法。

Toolbar

假设已经拿到了切换后的颜色 color,修改 Toolbar 的背景颜色和字体颜色:

toolbar.setBackground(color);toolbar.setTitleTextColor(color);

除了这两项,Toolbar 上可能还有操作按钮,像我这里左边的菜单和右边的搜索按钮。它们的颜色可以这样设置:

// 菜单按钮Drawable navigationIcon = toolbar.getNavigationIcon();if (navigationIcon != null) {    navigationIcon.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);}// 搜索按钮Menu toolbarMenu = toolbar.getMenu();Drawable searchIcon = toolbarMenu.getItem(0).getIcon();if (searchIcon != null) {    searchIcon.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);}

TabLayout

对于 TabLayout,涉及到的颜色有背景颜色、文字颜色(选中和未选中)、指示条:

tabLayout.setBackgroundResource(color);tabLayout.setTabTextColors(normalColor, selectedColor);tabLayout.setSelectedTabIndicatorColor(color);

NavigationView 存在一个头部,需要的话可以可以这样修改头部的背景和字体颜色:

View navigationHeader = navigationView.getHeaderView(0);if (isDay) {    navigationHeader.setBackgroundResource(R.drawable.side_nav_bar_day);} else {    navigationHeader.setBackgroundResource(R.drawable.side_nav_bar_night);}TextView tvHeader = (TextView) navigationHeader.findViewById(R.id.text_view);tvHeader.setTextColor(color);

接下来是目录部分的背景、字体颜色及图表颜色:

navigationView.setBackgroundResource(color);navigationView.setItemTextColor(color);navigationView.setItemIconTintList(color);

RecyclerView

通过遍历所有的 ChildView,对每一项进行颜色设置:

for (int position = 0; position < recyclerView.getChildCount(); position++) {    ViewGroup childView = (ViewGroup) binding.recyclerView.getChildAt(position);    // 设置颜色}

但要注意的是,RecyclerView 的内部使用 Recycler 和 RecyclerViewPool 实现了缓存,有可能出现当前使用的 item 颜色改变了,但是缓存里的没有变化。

解决方法是清理缓存,调用 Recycler 和 RecyclerViewPool 的 Clear() 方法,但前者无法直接调用,只能通过反射实现:

Class<RecyclerView> recyclerViewClass = RecyclerView.class;try {    Field declaredField = recyclerViewClass.getDeclaredField("mRecycler");    declaredField.setAccessible(true);    Method declaredMethod = Class.forName(RecyclerView.Recycler.class.getName()).getDeclaredMethod("clear");    declaredMethod.setAccessible(true);    declaredMethod.invoke(declaredField.get(binding.recyclerView));    RecyclerView.RecycledViewPool recycledViewPool = recyclerView.getRecycledViewPool();    recycledViewPool.clear();} catch (Exception e) {    e.printStackTrace();}

StatusBar

在 SDK 21 以上,允许我们修改状态栏的颜色:

if (Build.VERSION.SDK_INT >= 21 {    TypedValue typedValue = new TypedValue();    Resources.Theme theme = getTheme();    theme.resolveAttribute(R.attr.color, typedValue, true);    getWindow().setStatusBarColor(            ContextCompat.getColor(mContext, typedValue.resourceId));}

夜间模式的实现就到此,在重新设置颜色的部分比较繁琐,但这是我目前看到效果比较好的实现方式。效果如下:

项目地址

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 乌鲁木齐华凌后巷妹子在哪2018 千万不要买华凌热水器 美的华凌空调 华凌空调不制冷 新疆华凌集团 华凌变频空调 华凌冰箱怎么样 华凌冰箱怎样 smeg冰箱 海儿冰箱 冰箱洗衣机 华菱冰箱 hualing 华菱冰箱停产 华凯创意 华凯 华凯家具 华凯保险销售股份有限公司 华凯创意股吧 华创阳安 华创 华创集团 华创期货 建工华创 华创资本 华创会 华创阳安股吧 002371北方华创 华创阳安股票 华创e路航x20升级 华创e路航更新 华创机器人制造有限公司 广东华创鑫材实业有限公司 华创e路航x10 华创证券下载 华创e路航7寸 华创e路航x20 华创e路航x20端口 华创e路航x82 华创装饰公司 华创e路航 x10