独自のアプリ「氷と火の百科」(四):WebViewインタラクション、夜間モード

8134 ワード

簡単な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
このskipjsファイルはクライアントに置いて、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");

loadDataWithBase URLを使用して、データを表示します.
webView.loadDataWithBaseURL("file:///android_asset/", htmlData, "text/html", "utf-8", null);

これで簡単なJavaScriptとAndroidのインタラクションが完成し、効果は以下の通りです.
夜間モード
ナイトモードの実装については、主にD_clockはネギの大神が好きなこの文章で、簡単に言えば実現過程は以下の通りです.
  • stylesに「DayTheme」と「NightTheme」の2つのテーマを追加します.
  • レイアウトファイルでandroid:background=「?attr/colorBackground」のような色を使用して、現在のトピックの色に従うように色を設定します.
  • DayNightHelperを作成し、SharePreferencesを利用して現在のモードを保存、取得する.
  • ページsetContentViewより前に、現在のモードを判断し、setThemeによって現在のモードを設定する.
  • スクリーンの内容をBitmapに変えて、それに対して1つのグラデーションのアニメーションを実行して、切り替えの時のグラデーションの効果を実現します;
  • 傍受モード切替、TypedValueとThemeを通過する.resolveAttributeコードでThemeの色を取得し、コントロールの色を再設定します.

  • より詳細な内容は、原文を表示し、いくつかのコントロールの色設定方法を補足します.
    Toolbar
    切り替えた色colorを取得したと仮定し、Toolbarの背景色とフォント色を変更します.
    toolbar.setBackground(color);
    toolbar.setTitleTextColor(color);
    

    この2つのほかに、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
    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とRecyclerView Poolを使用してキャッシュが実現されており、現在使用されているitemの色が変わった可能性がありますが、キャッシュには変化はありません.
    解決策はキャッシュをクリーンアップし、RecyclerとRecyclerViewPoolを呼び出すClear()メソッドですが、前者は直接呼び出すことができず、反射でしか実現できません.
    Class 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));
    }
    

    ナイトモードの実現はここまでで、色を再設定する部分では煩雑ですが、これは私が今見ている効果的な実現方法です.効果は次のとおりです.
    プロジェクトアドレス