Android_Toolbarソース解析の使用と問題解決

21331 ワード

前言
なぜToolbarを使うのですか?
  • MD設計、全体視覚体験を最適化する.
    使用上の注意
  • V 7パッケージの互換性、themeの設定.
  • バージョンのAPIは互換性があります.
  • ソースの表示方法:
  • オンライン:Toolbar.javaアドレス:(Android 8.1バージョン)
  • Gitを使用してローカルにクローン化する:
    git clone android.google source.com/plotform/fr…
  • ウェブサイトAPIの説明
    説明:Toolbarは実際に導入すると二つのカバンがあることが分かります.一般的にv 7パッケージを使います.低バージョンに対応するため、公式サイトのv 7パッケージの下でToolbar APIは住所を説明します.
    Toolbarパッケージ構造:
    public class Toolbar extends View Group
    java.lang.Object
    ↳android.view.View
    ↳android.view.View Group
    ↳android.support.v 7.widget.Toolbar
    注意:
  • 一部の固有名詞の英語名を保留して、抽出しやすいです.
  • 翻訳内容は参考までに、間違ったところはご指摘ください.
    簡単な翻訳:
    Toolbarはアプリケーション内部で使用される汎用ナビゲーションバーであり、ActivityはToolbarを使用するために選択する必要があります.set Support Actionict Bar()方法ToolbarはActivrより多くの新しい機能をサポートしています.一つのToolbarは以下のオプションの要素の組み合わせを含んでいます.
  • A navigation button.これはUp arrow、navigation menu togggle、close、collapps、doneまたはanother glyphまたは他のapの選択かもしれません.このボタンは常にToolbar内の他のナビゲーションターゲットと指定された内容にアクセスするために使用されます.もし設定されたら、ナビゲーションボタンはToolbar内の高さ2479562に垂直に配置されます.
  • A brand ed loglogoイメージ.これは適応barの高さと任意の幅
  • です.
  • A title and subtitle.一級タイトルは現在のToolbarの階層位置とその中に含まれているコンテンツの道しるべであるべきです.二級タイトルは現在のコンテンツに関する拡張を指すべきです.一つのアプリがlogo画像を使用している場合、一級と二級タイトル
  • を無視することを強く考えなければなりません.
  • One or more custom view.このアプリケーションは任意のサブビューをToolbarに追加すると、彼らはレイアウトの中のこの位置に表示されます.もし1つの背viewのToolbar.LayoutParaamsがGravityの値を設定したらCENTER_です.HORIZONSTALでは、このビューはToolbarの他の要素が測定された後の残りの利用可能な位置の中間に表示されます.
  • An action menu.このaction menuはToolbarの最後の位置に固定され、いくつかの頻繁、重要または典型的な動作およびオプションのoverflow menuを提供して他の動作を実行します.設定されているならば、action menuはToolbarの最小高さ内に垂直に
  • を配置します.
    Android UIでは、開発者は、Toolbarの視覚的に異なる色スキームにより、アプリケーションのアイコンではなく、API 21およびそれ以上のアプリケーションの使用を奨励しないicon plus titleを標準レイアウトとして依存するべきである.
    ソース解析
    ソースの順序を見る(View/View Groupのサブクラスに対する):
  • 構造->onMeassure->onLayout->draw(viewに対する)/onDraw(View Groupに対する)
  • 関係と内部クラス
  • を実現する.
    その中のTitleソースの流れを取って説明します.他の設定子viewの流れは似ています.menuは少し複雑です.自分でソースを読むことができます.
    setTitleの流れは大体以下の通りです.
    効果図の実現&&分析
    プロジェクト環境:Android Studio 3.0.1+JDK 1.8
    テスト携帯電話:ALLVIEW X 5_ソウルPro Android 8.1.0、API 27
    言語:Kotlin
    ファイルの設定:
    build.gradleファイル
     dependencies {
         classpath 'com.android.tools.build:gradle:3.0.1'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
     }
    
    アプリ下のbuild.gradleファイル
     compileSdkVersion 28
     defaultConfig {
         applicationId "com.litchiny.testtoolbar"
         minSdkVersion 18
         targetSdkVersion 28
         versionCode 1
         versionName "1.0"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
     }
    
    gradle-wrapper.propertiesファイル
     distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
    
    効果図
    Toolbarを正しく使う3ステップ:
  • 元アクションバーの表示を削除します.
  • XmlレイアウトにToolbarの関連設定を設定します.
  • コードの設定に使用するToolbarの属性とクリックモニター(PS:一部の設定が有効になったのはバージョン21とそれ以上で有効になりました).
  • コード部分は以下の通りです.
    MainActivity.kt
     class ToolbarActivity : AppCompatActivity() {
        private lateinit var toolbar: Toolbar
        private lateinit var context: Context
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_toolbar)
            this.context = this
            initView()
            initListener()
        }
    
        private fun initView() {
            toolbar = findViewById(R.id.tb_show)
            //toolbar.title     :1   2   ,        3    , 1      ,  :    Q4
            toolbar.title = "    "                            //1 
            setSupportActionBar(toolbar)                          //3         Toolbar
    //        supportActionBar?.setDisplayHomeAsUpEnabled(true)   //      ,     :        navigationIcon
            toolbar.navigationIcon = ContextCompat.getDrawable(context, R.mipmap.left)   //       navigationIcon
            toolbar.logo = ContextCompat.getDrawable(context, R.mipmap.home)            //  logo,   title/subtitle   
    
    //        supportActionBar?.title = "      "               //2  
            toolbar.subtitle = "      "                        //  subtitle   
            toolbar.setTitleTextAppearance(context, R.style.ToolbarTitleText)          //  title     ,        16sp      
            toolbar.setSubtitleTextAppearance(context, R.style.ToolbarSubtitleText)    //  subtitle     ,     20sp      
            if (Build.VERSION.SDK_INT >= 21)
                toolbar.setElevation(2f)
        }
    
        private fun initListener() {
            toolbar.setNavigationOnClickListener {
                showToast("Navigation     ")
            }
    
            toolbar.setOnClickListener {
                showToast("id: ${it.id}")
            }
    
            setOnMenuItemClick()
        }
    
        // onOptionsItemSelected   
        private fun setOnMenuItemClick() {
            toolbar.setOnMenuItemClickListener {
                when (it.itemId) {
                    R.id.action_edit, R.id.action_share, R.id.action_about -> {
                        showToast("${it.title}     ")
                        true
                    }
                    else -> {
                        false
                    }
                }
            }
        }
    
        // setOnMenuItemClick  
        override fun onOptionsItemSelected(item: MenuItem?): Boolean {
            when (item?.itemId) {
                R.id.action_edit, R.id.action_share, R.id.action_about -> {
                    showToast("${item.title}     ")
                }
            }
            return super.onOptionsItemSelected(item)
        }
    
        //   menu       
        override fun onCreateOptionsMenu(menu: Menu?): Boolean {
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true
        }
    
        private fun showToast(descStr: String) {
            Toast.makeText(this, descStr, Toast.LENGTH_SHORT).show()
        }
    }
    
    activitytoolbar.xml
    xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/tb_show"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
    
    android.support.constraint.ConstraintLayout>
    
    style.xml
    xml version="1.0" encoding="utf-8"?>
    <resources>
        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <item name="colorPrimary">@color/colorPrimaryitem>
            <item name="colorPrimaryDark">@color/colorPrimaryDarkitem>
            <item name="colorControlNormal">@color/colorWhiteitem>
            <item name="android:windowBackground">@color/colorAccentitem>   
        style>
        
        
        <style name="ToolbarTitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
            <item name="android:textSize">16spitem>
            <item name="android:textColor">@color/colorWhiteitem>
        style>
    
        
        <style name="ToolbarSubtitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Subtitle">
            <item name="android:textSize">20spitem>
            <item name="android:textColor">@color/colorYellowitem>
        style>
    resources>
    
    colors.xml
    xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="colorPrimary">#3F51B5color>
        <color name="colorPrimaryDark">#303F9Fcolor>
        <color name="colorAccent">#FF4081color>
        <color name="colorWhite">#FFFFFFcolor>
        <color name="colorYellow">#f4f000color>
    resources>
    
    menumain.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"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context=".ToolbarActivity">
    
        <item android:id="@+id/action_edit"
            android:title="Search"
            android:orderInCategory="80"
            android:icon="@mipmap/search"
            app:showAsAction="ifRoom" />
    
        <item android:id="@+id/action_share"
            android:title="Share"
            android:orderInCategory="90"
            app:showAsAction="never" />
    
        <item android:id="@+id/action_about"
            android:title="About"
            android:orderInCategory="100"
            app:showAsAction="never"/>
    
        
        
        
        
        
    
    menu>
    
    遭遇した問題:
    Q 1:Logo、Title、SubTitleは単独でイベントをクリックできません.
    A 1:Toolbarに内蔵されているこの三つのコントロールを使わないか、Toolbarを引き継いで関連する方法を書き直します.
    Q 2:Logo、NavigationViewの画像のサイズは、適切に調整する必要があります.
    A 2:UIは適切なサイズ適応を与える(PS:効果図の画像サイズは128×128で、フォーマット:PNG)
    Q 3:Menuのmoreのアイコン表示は黒です.
    A 3:持参のthemeはDarkに設定し、popupはLightに設定します.
    参考:
     app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
     app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    
    Q 4:toolbar.titleがset Support Action Bar(toolbar)設定後に失効した問題
    A 4:AppComppatDelegateImpl.javaのソースコードを見てください.
    方法set Support Action BarでmActiverに再評価すると、titleをリセットします.アドレスはすでに変化していますので、直接toolbar.titleは無効になります.
    ソースは以下の通りです
     public void setSupportActionBar(Toolbar toolbar) {
        //...         
     
         if (toolbar != null) {
             final ToolbarActionBar tbab = new ToolbarActionBar(toolbar,
                     ((Activity) mOriginalWindowCallback).getTitle(), mAppCompatWindowCallback);
             mActionBar = tbab;
             mWindow.setCallback(tbab.getWrappedWindowCallback());
         } else {
             mActionBar = null;
             // Re-set the original window callback since we may have already set a Toolbar wrapper
             mWindow.setCallback(mAppCompatWindowCallback);
         }
         invalidateOptionsMenu();
     }
    
    参考文章は以下の通りです
  • wwww.jcodecraeer.com/a/anzhuokai...
  • jejin.im/post/5 a 30 de…
  • 最後に
    まとめ:
  • 実際にコードを書く時、Toolbarの内容や配置を頻繁に修正しないと、やはり一回でxmlに配置することをおすすめします.
  • Toolbar内のカスタム設定viewと現在知られているいくつかのサブビューの違いは大きくないので、説明を省略します.
    以上の内容に間違いがあったら、すぐに教えてください.ありがとうございます.
    転載先:https://juejin.im/post/5c40599f6fb9a049c0434eb0