Android
 Computer >> コンピューター >  >> システム >> Android

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成

Kriptofolio アプリ シリーズ - パート 2

では、実際にどのようにして新しいアプリの構築を開始するのでしょうか?あなたの最初の動きは何ですか? Android Studio を起動してコードに直接ジャンプするだけでよいと思われる場合は、もう一度考え直してください。それはまさに、良いことよりも多くのダメージを与える可能性があるため、私がしないようにアドバイスすることです.しかし、コードの最初の行をできるだけ早く書き始めたいという誘惑にかられます。

代わりに、UI モックアップを使用して賢明な計画を立てることに集中することをお勧めします。すべての優れた新しいアプリ プロジェクトは、そこから開始する必要があることを忘れないでください。このアプローチにより、多くの時間を失うことはなく、最初から高品質の製品を構築できます。

シリーズのこのパートでは、「Kriptofolio」(以前の「My Crypto Coins」)アプリのモックアップを紹介し、その作成方法について説明します。また、すべての UI レイアウトを作成します。これらのレイアウトは、何をコーディングするかを明確に示す強固な基盤となります。最後に、アプリをさまざまな言語にローカライズし、右から左に書かれた言語を処理する方法を学習します。

シリーズ コンテンツ

  • はじめに:2018 ~ 2019 年に最新の Android アプリを構築するためのロードマップ
  • パート 1:SOLID 原則の紹介
  • パート 2:Android アプリの作成方法:モックアップ、UI、XML レイアウトの作成 (ここにいます)
  • パート 3:アーキテクチャのすべて:さまざまなアーキテクチャ パターンとアプリでの使用方法を探る
  • パート 4:Dagger 2 を使用してアプリに依存性注入を実装する方法
  • パート 5:Retrofit、OkHttp、Gson、Glide、およびコルーチンを使用して RESTful Web サービスを処理する

モックアップ

プロジェクトのモックアップを作成するには、さまざまな方法があります。最も簡単な方法は、鉛筆と紙を用意して、その上に描き始めることです。最良の部分は、この方法は費用がかからず、すぐに開始できることです。ああ、ほとんど忘れていましたが、元に戻す機能がないため、消しゴムも用意する必要があります。 ?

私と同じように、より多くの機能が必要だと感じている場合は、詳細なモックアップを作成するための特別なソフトウェアの使用を検討してください。お金を投資して購入し、使い方を学ぶ時間が必要になるとしても、私は紙と鉛筆よりもソフトウェアを使用することを好みます.

市場には、選択できるさまざまなソフトウェア オプションがあります。どれがすべてのニーズに最も適しているかを独自に調査する必要があります。現在、すべてのプロジェクトのモックアップで、デスクトップ アプリ用の Balsamiq Mockups を使用しています。 Balsamiq は、迅速かつ効果的で、非常に使いやすいワイヤー フレーミング ソフトウェアです。かなり満足しているので、Androidアプリの作成にオススメですので、お気軽にお試しください。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成

よく考え抜かれた非常に詳細なモックアップを作成することで、My Crypto Coins アプリ プロジェクトを開始しました。すべてを非常に詳細な方法で作成すれば、間違いを避けることができると思いました。また、開発過程でいきなり機能を変更して時間を無駄にすることもありません。優れたモックアップを作成するために多大な努力を払った場合、少し想像力を働かせれば、最終製品を見て感じることができます。

私の目標は、最終製品で見られるように、モックアップですべてを定義することでした。そのために、焦らず、必要なだけ時間を費やすようにしました。 My Crypto Coins アプリの最終的なモックアップは次のとおりです。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
Balsamiq Mockups ソフトウェアで作成した My Crypto Coins アプリのモックアップ

ストック デザイン — 素材

もう 1 つ重要なことは、アプリのビジュアル デザインです。この記事の執筆時点では、Material Design は、すべての Android アプリに対して Google が推奨するストック ビジュアル デザインです。想像してみてください — ストック デザインを間違えることはありません。

My Crypto Coins アプリでは、マテリアル デザインを使用します。このアプリは、詳細なオンライン ガイドラインで定義されているベスト プラクティスに従っています。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成

Material.io/guidelines — このプロジェクトのデザイン ガイドラインとなる公式のマテリアル デザイン リビング スペック ドキュメント。

レイアウト

アプリのワイヤーフレームが準備できたら、実際の UI を作成します。ここでもコードの記述に飛び込むことができますが、なぜ急ぐのでしょうか?代わりに、すべての XML レイアウトの作成に集中することをお勧めします。ここでの私のアドバイスは、XML に多くのことを入れるほど、記述する必要のあるコードが少なくなるということです。

Android チームは、XML レイアウトに新しい機能を追加することで、UI を構築する方法を常に改善しています。目的の外観を実現するために数行のコードを記述したくなることがあります。ただし、このトピックをより深く調査して、コードなしで実行できるかどうかを確認することをお勧めします。覚えておいてください:コードが少ないほど、プロジェクトがきれいに見えます。また、他の開発者にとってより理解しやすく、維持しやすくなります。

最後に、すべての XML レイアウトを作成すると、アプリを作成したような気分になります。起動して、エンド ユーザーがどのように感じるかを確認できます。偽のデータが表示され、何もしないことは問題ではありません。大幅な変更を行う最後のチャンスです。

他の誰かのためにアプリを構築している場合は、それを発表する絶好の機会です。土壇場で驚くべき変更を行うよう求められるかもしれません。そうすれば、決して使用されない機能のコードを書くことを避けることができます。多くの人は十分な想像力を持っておらず、最初に見て、触って、それが自分の望むものかどうかを判断する必要があります.そのため、レイアウトを作業プロセスの最後のステップに残さないでください。

このアプリでは、すべての最新の Android アプリに共通するさまざまなコンポーネントを使用します:

  • CoordinatorLayout — 非常に強力な FrameLayout です。その主な魅力は、その中のビューのアニメーションとトランジションを調整できることです。
  • AppBarLayout — スクロール ジェスチャなど、マテリアル デザインのアプリ バー コンセプトの多くの機能を実装する垂直方向の LinearLayout。
  • ツールバー — アプリケーション レイアウト内で使用するアクション バーの一般化
  • CollapsingToolbarLayout — 折りたたみアプリ バーを実装する Toolbar のラッパー。 AppBarLayout の直接の子として使用するように設計されています。
  • ConstraintLayout — ウィジェットの配置とサイズを柔軟に設定できる ViewGroup。強化された RelativeLayout を想像してみてください。
  • SwipeRefreshLayout — スワイプして更新するユーザー インターフェース パターンを完全に実装できるようにするウィジェット。縦方向のスワイプを検出し、特徴的なプログレス バーを表示し、アプリでコールバック メソッドをトリガーします。
  • FloatingActionButton — アプリの UI で主要なアクションをトリガーする円形のボタン

メイン画面では、これらすべてのコンポーネントを組み合わせて使い、優れた UI/UX を作成します。ユーザーは、レイアウトの上部を展開したり折りたたんだりして、すべての暗号通貨ポートフォリオの合計値を見つけることができます.過去 24 時間の価値の変化を確認し、選択した法定通貨を変更できます。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
メイン画面のレイアウト作成

もちろん、これらの 9 つ以外のコンポーネントもあります。特定のケースでどれを使用するかを知るには、コンポーネント パレット全体をマスターすることが非常に重要です。モバイルのトレンドは時々変化するため、パレットも拡大します。

すべてのコンポーネントについて話すつもりはありませんが、自分で調査することをお勧めします。私にとって、それらを理解する最善の方法は、Android Studio の自動ドラッグ &ドロップ ツールを使用する代わりに、手動で XML レイアウトを作成することです。

スタイル、色、寸法、文字列、アイコン

一見すると、このセクションのタイトルに記載されていることは重要ではないように見えるかもしれません。ただし、モダンで排他的なアプリにしたい場合は、アプリでそれらを作成するときに努力してください.このブログ投稿シリーズは、最新の Android アプリを構築する方法であることを忘れないでください。それがどんなに間違っていても、人々は通常、あなたのアプリをその機能ではなく、最初に見た目で判断します。

したがって、これは最初から新しいユーザーの愛を獲得する絶好のチャンスです。これらは私のヒントです:

  • XML レイアウト ファイルを作成するときは、ビューのいくつかの共通属性を繰り返す場所を認識する必要があります。それらを別の XML スタイルとして定義するように移動します。そうすれば、XML レイアウト ファイルが短くなります。別の場所からアプリのスタイリングのすべての側面を制御できます。それがあなたにどんな利益をもたらすか想像してみてください。たとえば、ユーザーがアプリのスキン (明るい、暗いなど) を選択できるようにすることができます。
  • アプリのすべての色も別のファイルで定義し、すぐに変更して外観を試すことができます。場合によっては、同じ製品に新しい命を吹き込み、新しい色でリフレッシュするだけでユーザーを再び惹きつけることができます。素敵な色を選ぶのに役立つウェブサイトはたくさんありますが、私のお気に入りは MaterialPalette.com です。ぜひご覧ください。
  • 別のファイルでアプリのサイズを定義します。これにより、さまざまなサイズの画面で適切に表示されるようにアプリを調整できます。
  • すべての文字列をハードコーディングしないでください。忘れると、Android Studio から通知されます。それを無視しないでください。文字列を分離する最大の利点は、アプリをさまざまな言語に翻訳できることです。
  • アプリでアイコンを使用する場合は、常に XML ベクター ドローアブル形式を優先してください。これが新しい推奨基準であり、ピクセル化を回避する賢い方法です。コミュニティから専門的に作成された多くのマテリアル デザイン スタイルのアイコンを見つけるには、MaterialDesignIcons.com をチェックしてください。このウェブサイトを使用して My Crypto Coins アプリのアイコンを取得しました。

リサイクラー ビュー

My Crypto Coins アプリのメイン画面は、ユーザーが保持している暗号通貨のリストで構成されます。この目的には、RecyclerView ウィジェットが最適です。大規模なデータ セット (または頻繁に変更されるデータ) に基づいて要素のスクロール リストを表示するウィジェットです。

その利点から、RecyclerView はリスト画面の作成に推奨されるコンポーネントです。これは、単純な ListView コンポーネントのより高度で柔軟なバージョンです。それについても後で話します。この部分では、レイアウトのみを作成しています。コーディングには集中していません。

アプリを視覚的に確認するには、コードを記述して RecyclerView を実装する必要があります。 RecyclerView を実装する手順は次のとおりです:

1. RecyclerView コンポーネントを追加します。

私たちの MainActivity レイアウトは activity_main.xml です .このレイアウトには content_main.xml が含まれています フラグメントであるレイアウト。この MainActivityListFragment レイアウトは fragment_main_list.xml を膨らませます .したがって、ここに RecyclerView コンポーネントを追加する必要があります。

...
<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerview_fragment_main_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorForMainListBackground"
    android:clipToPadding="false"
    android:paddingBottom="72dp"
    android:paddingTop="5dp"
    android:scrollbarStyle="outsideOverlay"
    android:scrollbars="vertical" />
...

ご覧のとおり、RecyclerView を構成して、下部にパディング スペースを残します。これは、最後のリスト項目が FloatingActionButton で覆われないようにするためです。また、利用できるように垂直スクロールバーをオンにします。

2. RecyclerView の行レイアウトを作成します。

最初の目的として、各行に項目名のみを設定します。簡略化したレイアウトは次のようになります。

<android.support.v7.widget.CardView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="@dimen/main_cardview_list_item_outer_top_bottom_margin"
    android:layout_marginEnd="@dimen/main_cardview_list_item_outer_start_end_margin"
    android:layout_marginStart="@dimen/main_cardview_list_item_outer_start_end_margin"
    android:layout_marginTop="@dimen/main_cardview_list_item_outer_top_bottom_margin"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"
    app:cardBackgroundColor="@color/colorForMainListItemBackground">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/main_cardview_list_item_inner_margin">
        ...
        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/item_name"
            style="@style/MainListItemPrimeText"
            android:layout_marginEnd="@dimen/main_cardview_list_item_text_between_margin"
            android:layout_marginStart="@dimen/main_cardview_list_item_inner_margin"
            app:layout_constraintBottom_toTopOf="@+id/item_amount_symbol"
            app:layout_constraintEnd_toStartOf="@+id/guideline1_percent"
            app:layout_constraintStart_toEndOf="@+id/item_image_icon"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_chainStyle="spread"
            tools:text="@string/sample_text_item_name" />
        ...
    </android.support.constraint.ConstraintLayout>

</android.support.v7.widget.CardView>

3.データ アダプタ クラスを作成します。

今のところ、アダプターは文字列データを受け入れます。後で、別のクラス データ モデルを作成する必要があります。 1 つの文字列だけではなく、より多くの情報を渡す必要があります。

class MainRecyclerViewAdapter(val dataList: ArrayList<String>) : RecyclerView.Adapter<MainRecyclerViewAdapter.CustomViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.fragment_main_list_item, parent, false)
        return CustomViewHolder(v)
    }

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        holder.txtName?.text = dataList[position]
    }

    override fun getItemCount(): Int {
        return dataList.size
    }


    inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val txtName = itemView.findViewById<TextView>(R.id.item_name)
    }
}

4. RecyclerView をカスタム アダプターに接続します。

class MainActivityListFragment : Fragment() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var recyclerAdapter: MainRecyclerViewAdapter

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val v: View = inflater.inflate(R.layout.fragment_main_list, container, false)

        recyclerView = v.findViewById(R.id.recyclerview_fragment_main_list)

        return v
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {

        super.onActivityCreated(savedInstanceState)

        setupList()
    }

    private fun setupList() {

        val data = ArrayList<String>()
        data.add("Bitcoin")
        data.add("Etherium")
        data.add("Ripple")
        data.add("Bitcoin Cash")
        data.add("Litecoin")
        data.add("NEO")
        data.add("Stellar")
        data.add("EOS")
        data.add("Cardano")
        data.add("Stellar")
        data.add("IOTA")
        data.add("Dash")
        data.add("Monero")
        data.add("TRON")
        data.add("NEM")
        data.add("ICON")
        data.add("Bitcoin Gold")
        data.add("Zcash")
        data.add("Verge")

        recyclerView.layoutManager = LinearLayoutManager(activity)
        recyclerAdapter = MainRecyclerViewAdapter(data)
        recyclerView.adapter = recyclerAdapter
    }
}

終わり!メイン画面は次のようになります:

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
メイン画面

リストビュー

このプロジェクトでは、すでに保有している仮想通貨を追加できる画面に ListView を使用します。近年の欠点のため、ほとんど使用されていません.

RecyclerView で同じ機能を簡単に作成できるのに、なぜ My Crypto Coins アプリで使用することにしたのか疑問に思われている方も多いと思います。

ただし、このプロジェクトは最初にトレーニング目的で作成されたことを思い出してください。 ListView とその仕組みについての洞察を得ることは有益だと思いました。開発者は、レガシー コードで ListView に遭遇する可能性があります。さらに、作成するリストは非常に単純であるため、ListView の技術的な制限によって問題が生じることはありません。

ListView を実装するために必要な非常によく似た手順に従いましょう:

1. ListView コンポーネントを追加します。

最初に行うことは、ListView を AddSearchActivity に追加することです .アクティビティ レイアウト ファイル activity_add_search.xml を開く content_add_search.xml が含まれていることがわかります。 .そこに ListView コンポーネントを追加します。

...
<ListView
    android:id="@+id/listview_activity_add_search"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="vertical" />
...

2. ListView の行レイアウトを作成します。

前と同じように、最初の目的のために、各行の項目名のみを設定します。簡略化したレイアウトは次のとおりです:

<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/add_search_list_item_inner_margin">
    ...
    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/item_name"
        style="@style/AddSearchListItemPrimeText"
        android:layout_marginEnd="@dimen/add_search_list_item_text_between_margin_2x"
        android:layout_marginStart="@dimen/add_search_list_item_text_between_margin"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/item_symbol"
        app:layout_constraintStart_toEndOf="@+id/item_image_icon"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="@string/sample_text_item_name" />
    ...
</android.support.constraint.ConstraintLayout>

3.データ アダプタ クラスを作成します。

RecyclerView と同様に、ListView アダプターは今のところ文字列データのみを受け入れて項目名を取得し、画面に表示します。後で、別のクラス データ モデルを使用します。この部分に関しては、暗号通貨のタイトルのみを表示する非常に単純なリストを作成したいと考えています。カスタム アダプタを作成する代わりに、デフォルトの ArrayAdapter を使用できます。

class AddSearchListAdapter(context: Context, private val dataSource: ArrayList<String>) : BaseAdapter() {

    private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val view: View
        val holder: CustomViewHolder

        if (convertView == null) {

            view = inflater.inflate(R.layout.activity_add_search_list_item, parent, false)

            holder = CustomViewHolder()
            holder.nameTextView = view.findViewById(R.id.item_name)

            view.tag = holder

        } else {

            view = convertView
            holder = convertView.tag as CustomViewHolder
        }

        val nameTextView = holder.nameTextView

        nameTextView.text = getItem(position) as String

        return view
    }

    override fun getItem(position: Int): Any {
        return dataSource[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong();
    }

    override fun getCount(): Int {
        return dataSource.size
    }


    inner class CustomViewHolder {
        lateinit var nameTextView: AppCompatTextView
    }

}

アダプタ コードでわかるように、 CustomViewHolder を作成して object ViewHolder パターンを使用します。リスト行ビューの参照を格納します。 findViewById() を呼び出す メソッドは数回しか発生しません。これにより、リストのスクロールをスムーズかつ効率的に行うことができます。

ListView では、ViewHolder パターンを使用する必要はありません。 RecyclerView のアダプターは、使用を強制するため、デフォルトでそのような保護を提供します。

4. ListView をカスタム アダプターに接続します。

デフォルトの ArrayAdapter では val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, data) のようになります .これが ListView コンポーネントの優れた点です。必要に応じて、独自のアダプターや行レイアウトを作成せずに、単純なリストを非常に迅速に作成できます (手順 2 と 3 をスキップします)。

class AddSearchActivity : AppCompatActivity() {

    private lateinit var listView: ListView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add_search)
        setSupportActionBar(toolbar2)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

        val data = ArrayList<String>()
        data.add("Bitcoin")
        data.add("Etherium")
        data.add("Ripple")
        data.add("Bitcoin Cash")
        data.add("Litecoin")
        data.add("NEO")
        data.add("Stellar")
        data.add("EOS")
        data.add("Cardano")
        data.add("Stellar")
        data.add("IOTA")
        data.add("Dash")
        data.add("Monero")
        data.add("TRON")
        data.add("NEM")
        data.add("ICON")
        data.add("Bitcoin Gold")
        data.add("Zcash")
        data.add("Verge")

        val adapter = AddSearchListAdapter(this, data)

        listView = findViewById(R.id.listview_activity_add_search)
        listView.adapter = adapter

    }
    ...
}

ListView のセットアップが完了しました!

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
クリプトコイン(-s)追加画面

検索ビュー

すべての暗号通貨がリストされている同じ画面で、SearchView も追加する必要があります。検索は、名前を入力して特定の暗号通貨を見つけたいユーザーにとって便利な機能です。この部分では、機能を完全に構築するのではなく、視覚的な部分を実装するだけです。次の手順に従って、SearchView をプロジェクトに追加します。

1.検索可能な構成を XML で宣言します。

検索可能な構成ファイルは、xml という名前の res ディレクトリに追加する必要があります。ここで、動作を定義する SearchView コンポーネントの属性を指定できます。

<searchable
    xmlns:android="https://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/search_hint">
</searchable>

2.検索可能なアクティビティとなる新しいアクティビティを作成します。

AppCompatActivity() を拡張する新しい空のアクティビティを作成します .名前を AddSearchActivity にします .

3. Android マニフェスト ファイルで新しく作成されたアクティビティを検索可能に指定します。

<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.baruckis.mycryptocoins">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
        <activity
            android:name=".AddSearchList.AddSearchActivity"
            android:launchMode="singleTop"
            android:parentActivityName=".MainList.MainActivity"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>
        ...
    </application>

</manifest>

Android システムに検索プロセスを処理させます。そのため、AddSearchActivity のアクティビティ要素にインテント アクション検索とメタデータを追加します。 .メタデータには名前とリソースがあり、res/xml フォルダーにある検索可能な構成ファイルにリンクされています。

4.検索メニューを作成します。

res/menu フォルダー内に、メニュー リソース ファイルを作成します。

<menu xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/search"
        android:icon="@drawable/ic_search"
        android:title="@string/action_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView" />
</menu>

5.アクティビティに検索メニューを追加します。

Android 検索ウィジェットをメニュー アクション ビューとして追加します。

class AddSearchActivity : AppCompatActivity() {
    ...
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {

        menuInflater.inflate(R.menu.menu_search, menu)

        val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
        val searchView = menu?.findItem(R.id.search)?.actionView as SearchView
        searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName))
        searchView.maxWidth = Integer.MAX_VALUE

        return true
    }
}

これで SearchView がアクティビティに追加されました。まだ検索機能が機能していません。しかし、この部分で必要に応じて実装しました。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
仮想通貨(-s)画面を追加 — 検索機能

設定

最新の Android アプリを作成する場合は、設定画面を含めて、ユーザーにアプリ設定へのアクセスを許可することをお勧めします。アプリに設定を含めることで、ユーザーはアプリの機能の一部を制御できるようになり、ユーザーの満足度が向上します。アプリの動作を制御できるようになりました。そこで、My Crypto Coins アプリの設定画面も作成します。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
ギャラリー テンプレートからの新しい設定アクティビティ

Android Studio テンプレートを使用して設定画面を作成すると、必要なすべてのコードが生成されます。このブログ投稿の執筆時点では、デフォルトで、設定アクティビティは設定ヘッダーで生成されます。これは、最初は少数の設定のみを予定しているような小さなアプリに必要なことではありません。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
設定ヘッダーを含むデフォルト設定テンプレート

したがって、すべてを手動でビルドします。設定画面は XML ライクなレイアウトで設計されています。このブログ投稿の視覚的な部分だけをもう一度作成してみましょう:

1.設定画面の XML ファイルを作成します。

res/xml ディレクトリに配置する設定画面の XML ファイルを作成します。

<PreferenceScreen xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools">
    <PreferenceCategory android:title="@string/pref_general_category_title">
        <ListPreference
            android:defaultValue="@string/pref_default_language_value"
            android:entries="@array/pref_language_list_entries"
            android:entryValues="@array/pref_language_list_values"
            android:icon="@drawable/ic_translate"
            android:key="language_list"
            android:summary="@string/pref_default_language_entry"
            android:title="@string/pref_language_title"
            tools:summary="@string/pref_default_language_entry" />

        <ListPreference
            android:defaultValue="@string/pref_default_fiat_currency_value"
            android:entries="@array/pref_fiat_currency_list_entries"
            android:entryValues="@array/pref_fiat_currency_list_values"
            android:icon="@drawable/ic_cash"
            android:key="fiat_currency_list"
            android:summary="@string/pref_default_fiat_currency_entry"
            android:title="@string/pref_fiat_currency_title"
            tools:summary="@string/pref_default_fiat_currency_entry" />

        <ListPreference
            android:defaultValue="@string/pref_default_date_format_value"
            android:entries="@array/pref_date_format_list_entries"
            android:entryValues="@array/pref_date_format_list_values"
            android:icon="@drawable/ic_date_range"
            android:key="date_format_list"
            android:summary="@string/pref_default_date_format_entry"
            android:title="@string/pref_date_format_title"
            tools:summary="@string/pref_default_date_format_entry" />

        <SwitchPreference
            android:defaultValue="true"
            android:icon="@drawable/ic_calendar_clock"
            android:key="24h_switch"
            android:summary="@string/pref_24h_switch_summary"
            android:title="@string/pref_24h_switch_title" />

    </PreferenceCategory>

    <PreferenceCategory android:title="@string/pref_support_category_title">

        <Preference
            android:icon="@drawable/ic_star"
            android:title="@string/pref_rate_app_title" />

        <Preference
            android:icon="@drawable/ic_share"
            android:title="@string/pref_share_app_title" />

        <Preference
            android:icon="@drawable/ic_attach_money"
            android:summary="@string/pref_donate_view_summary"
            android:title="@string/pref_donate_view_title" />

        <Preference
            android:icon="@drawable/ic_currency_btc"
            android:summary="@string/pref_donate_crypto_summary"
            android:title="@string/pref_donate_crypto_title" />

    </PreferenceCategory>

    <PreferenceCategory android:title="@string/pref_support_about_title">

        <Preference
            android:icon="@drawable/ic_web"
            android:summary="@string/pref_website_summary"
            android:title="@string/pref_website_title" />

        <Preference
            android:icon="@drawable/ic_human_greeting"
            android:summary="@string/pref_author_summary"
            android:title="@string/pref_author_title" />

        <Preference
            android:icon="@drawable/ic_github_circle"
            android:summary="@string/pref_source_summary"
            android:title="@string/pref_source_title" />

        <Preference
            android:icon="@drawable/ic_file_multiple"
            android:title="@string/pref_open_source_title" />

        <Preference
            android:icon="@drawable/ic_copyright"
            android:summary="@string/pref_license_summary"
            android:title="@string/pref_license_title" />

        <Preference
            android:icon="@drawable/ic_info_outline"
            android:summary="@string/pref_app_summary"
            android:title="@string/pref_app_title" />

    </PreferenceCategory>

</PreferenceScreen>

2.設定フラグメントを作成します。

次に、単純な空白のフラグメントを作成する必要があります — SettingsFragmentPreferenceFragment() を拡張する必要があります .このフラグメントは、作成した XML リソースから設定を作成します。将来、このフラグメントには、XML 設定を拡張するために必要なすべてのメソッドが含まれます。また、設定が変更されたときにコールバックを提供します。

class SettingsFragment : PreferenceFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        addPreferencesFromResource(R.xml.pref_main);
    }
}

3.設定アクティビティを作成します。

設定フラグメントの準備ができたら、新しいアクティビティを作成しましょう — AppCompatPreferenceActivity 、これは PreferenceActivity() を拡張します .このクラスは、すべてのデバイスとバージョンにわたって互換性を提供します。

abstract class AppCompatPreferenceActivity : PreferenceActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        delegate.installViewFactory()
        delegate.onCreate(savedInstanceState)
        super.onCreate(savedInstanceState)
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        delegate.onPostCreate(savedInstanceState)
    }

    val supportActionBar: ActionBar?
        get() = delegate.supportActionBar

    fun setSupportActionBar(toolbar: Toolbar?) {
        delegate.setSupportActionBar(toolbar)
    }

    override fun getMenuInflater(): MenuInflater {
        return delegate.menuInflater
    }

    override fun setContentView(@LayoutRes layoutResID: Int) {
        delegate.setContentView(layoutResID)
    }

    override fun setContentView(view: View) {
        delegate.setContentView(view)
    }

    override fun setContentView(view: View, params: ViewGroup.LayoutParams) {
        delegate.setContentView(view, params)
    }

    override fun addContentView(view: View, params: ViewGroup.LayoutParams) {
        delegate.addContentView(view, params)
    }

    override fun onPostResume() {
        super.onPostResume()
        delegate.onPostResume()
    }

    override fun onTitleChanged(title: CharSequence, color: Int) {
        super.onTitleChanged(title, color)
        delegate.setTitle(title)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        delegate.onConfigurationChanged(newConfig)
    }

    override fun onStop() {
        super.onStop()
        delegate.onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        delegate.onDestroy()
    }

    override fun invalidateOptionsMenu() {
        delegate.invalidateOptionsMenu()
    }

    private val delegate: AppCompatDelegate by lazy {
        AppCompatDelegate.create(this, null)
    }
}

4.設定アクティビティを作成します。

class SettingsActivity : AppCompatPreferenceActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setupActionBar()

        fragmentManager.beginTransaction().replace(android.R.id.content, SettingsFragment()).commit()
    }

    private fun setupActionBar() {
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    override fun onMenuItemSelected(featureId: Int, item: MenuItem): Boolean {
        val id = item.itemId
        if (id == android.R.id.home) {
            if (!super.onMenuItemSelected(featureId, item)) {
                NavUtils.navigateUpFromSameTask(this)
            }
            return true
        }
        return super.onMenuItemSelected(featureId, item)
    }
}

5.メイン メニューに設定項目を追加します。

<menu xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    tools:context="com.baruckis.mycryptocoins.MainList.MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never" />
</menu>

6.設定がオーバーフロー メニューから選択されたときに、新しく作成された設定アクティビティを起動します。

class MainActivity : AppCompatActivity() {
    ...
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_settings -> {
                startActivity(Intent(this@MainActivity, SettingsActivity::class.java));
                return true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

7. Android マニフェスト ファイルで新しく作成された設定アクティビティを指定します。

<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.baruckis.mycryptocoins">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
        <activity
            android:name=".Settings.SettingsActivity"
            android:label="@string/title_activity_settings"
            android:parentActivityName=".MainList.MainActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.baruckis.mycryptocoins.MainList.MainActivity" />
        </activity>
    </application>

</manifest>

おめでとうございます。ようやくツールバーのメニュー項目から設定を開始できます。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
設定画面

サードパーティ ライブラリの使用 — Gmail スタイルのフリップ サークル ボタン ビュー

OK、サード パーティ ライブラリ (開発プラットフォームの元のベンダー以外の開発者によって作成されたコード) の使用についてはさまざまな意見があります。どれくらいの期間、どれだけうまくサポートされるかがはっきりしないため、避ける人もいます。一方、開発プロセスを加速できるので、それらを使用する人もいます。

それらを使用するかどうかの決定は、特定のケースに依存する必要があります。ライブラリを独自に調査し、すべての要件に適合する柔軟性があるかどうかを判断する必要があります。

My Crypto Coins アプリで、円の画像ビューを作成したい状況があります。この画像は、円の中に特定の暗号通貨のアイコンを表示する必要があります。しかし、アイコンが存在しない場合は、暗号通貨コードの最初の 3 文字を表示したいと思います。

それに加えて、画像をクリックして選択できるようにしたいと考えています。選択は、短いフリップ ビュー アニメーションとして表示する必要があります。

私が説明したこのすべての UX は、もともと私が発明したものではありません。 Gmail アプリでも同様の動作を見つけることができ、非常に優れています。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
Gmail アプリのフリップ サークル表示アニメーション

しかし、どうやってそれを作成するのでしょうか?実際、円形の画像ビューは、Android Studio コンポーネント パレットにあるデフォルトのコンポーネントでさえありません。

難しい方法ですべてを自分で作成しようとすることもできますが、これは時間とエネルギーを浪費する可能性があります。代わりに、そのために特別に作成された多くのオープン ソース ライブラリの 1 つを実装することを選択できます。

私の UI/UX 要件については、GitHub davideas/FlipView でライブラリを見つけました。いくつかの調査の後、私はそれが本当に専門的に作られたと判断しました.実装は簡単で、試してみるのに十分な期間サポートされています。使用を開始するには、次の簡単な手順に従います。

1.依存関係を追加します。

ライブラリをプロジェクトにインポートします。

dependencies {
  implementation 'eu.davidea:flipview:1.1.3'
}

2.使用してください。

Android の通常のアプリ属性とカスタム アプリ属性を使用して FlipView を構成します。簡単じゃないですか?

<android.support.v7.widget.CardView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    ...
        <eu.davidea.flipview.FlipView
            android:id="@+id/item_image_icon"
            style="@style/FlipView"
            android:clickable="true"
            android:focusable="true"
            app:layout_constraintBottom_toTopOf="@+id/item_ranking"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    ...
</android.support.v7.widget.CardView>

したがって、車輪を再発明しないでください。結果をより速く提供するために、最初に何らかのライブラリを使用することを常に検討してください。また、プロジェクトが乱雑になった場合、それは古いライブラリが原因ではなく、コードをどれだけうまく構成しているかに問題があります。プロジェクトが十分にモジュール化されている場合、問題はありません。しかし、それは別のトピックであり、プロジェクト アーキテクチャについては後のブログ記事で説明します。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
メイン画面リスト内で使用されるフリップ ビュー

RTL サポートによるローカリゼーション

このアプリを作成することを決めたとき、デフォルトの英語の UI で作成するだけでなく、開発の最初から母国語であるリトアニア語に翻訳することを目標に設定しました。

この目標が、Android のローカリゼーションについて学ぶきっかけになりました。私が見つけたのは、複数の言語のサポートを追加するのは非常に簡単だということです。前に述べたように、最初にすべての文字列をstrings.xmlファイルに分離する必要があります。その後、Android Studio 内で Translations Editor ツールを起動できます。これにより、新しい言語サポートを追加できます。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成

インターフェイスが非常に直感的であることがわかります。次に、strings.xml ファイルの各文字列を新しい言語に翻訳する必要があります。新しいファイルは、IDE によって別のディレクトリに生成されます。たとえば、リトアニア語の場合、values-lt/strings.xml です。 .それでおしまい! ?

Android デバイスのシステム言語を翻訳先の言語に切り替えてアプリを実行すると、すべての UI が自動的に翻訳に更新されます。さらに、My Crypto Coins アプリでは、後で実行時に言語を切り替える機能を追加する予定です。そのため、設定画面内に言語スイッチャーが表示されます。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
設定画面 — 言語リトアニア語

アプリをさまざまな言語に翻訳すると、対象ユーザーが確実に広がります。アラビア語、ヘブライ語、ペルシア語など、右から左へ (RTL) で記述されるいくつかの特殊言語のサポートを追加して、さらに進んでみませんか。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成

実際、RTL サポートを追加することはまったく難しくありません。マニフェスト ファイルに support 属性を追加するだけです:

<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.baruckis.mycryptocoins">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
    </application>

</manifest>

おめでとうございます。アプリが RTL をサポートするようになりました。ただし、すべてがすぐに正しく機能することを盲目的に信頼することはできません。自分でどれだけサポートされているかを確認する必要があります。そのためには、RTL 言語の 1 つをデバイスの主要言語として選択します。

RTL に関するいくつかのヒント:

  • すべてのレイアウトで、すべての Left を置き換える必要があります と Right Start のレイアウト プロパティ そして End 同等。例:android:paddingLeft android:paddingStart に置き換える必要があります .
  • RTL 用の特別なドローアブルがない場合は、現在のドローアブルを特別な autoMirrored でミラーリングすることをお勧めします。
<vector xmlns:android="https://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:autoMirrored="true"
    android:tint="@color/colorForPreferenceIcon"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M1.5,4V5.5C1.5,9.65 3.71,13.28 7,15.3V20H22V18C22,15.34 16.67,14 14,14C14,14 13.83,14 13.75,14C9,14 5,10 5,5.5V4M14,4A4,4 0 0,0 10,8A4,4 0 0,0 14,12A4,4 0 0,0 18,8A4,4 0 0,0 14,4Z" />
</vector>
  • RTL の代わりに LTR が必要な場所がある場合は、それも可能です。たとえば、レイアウトを強制的に LTR にするには、android:layoutDirection="ltr" を追加するだけです その景色に。 android:textDirection="ltr" を使用するよりも、テキスト ビュー内でテキストの方向を強制する必要がある場合 .
Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成

ところで、Translations Editor を使用する場合、プロの翻訳サービスを注文できる非常に便利な機能があります。個人的にはヘブライ語について何も知りませんが、My Crypto Coins プロジェクトのサンプル RTL 言語としてヘブライ語のサポートを追加するという目標を設定しました。したがって、この機能は試してみるのに非常に良いアイデアのように思えました。数回クリックするだけで、英語からヘブライ語への翻訳を IDE から直接注文できました。

Android アプリの構築を開始する方法:モックアップ、UI、および XML レイアウトの作成
翻訳サービスを注文する

最終的な考え

シリーズの第 2 部では、詳細なモックアップに基づいた初期コードを使用して、すべての UI レイアウトを作成しました。混乱を避けるために、各トピックについてあまり詳しく説明しませんでした。私の目標は、全体像を見る方法、最初に細部に焦点を当て、後でコストのかかる間違いを避ける方法を示すことでした.

十分にカバーされていないものを見つけた場合は、それを出発点として使用して、独自の調査を行ってください。ウェブ上には、学ぶべき優れたリソースが常にたくさんあります。 ?

リポジトリ

この部分のために作成されたすべての XML レイアウトとコードは、ここにあります:

GitHub でソースを表示

あちゅ!読んでくれてありがとう!この投稿は、2018 年 5 月 14 日に個人ブログ www.baruckis.com で最初に公開したものです。


  1. Android に Edge をインストールして使用する方法

    Microsoft の Edge には、既定のブラウザーを快適に使用できるようにする機能が満載です。現在は廃止された Internet Explorer の使用に勝るものはありません。 そして、あなたがファンなら、Edge エクスペリエンスをスマートフォンに持ち込むのは良い考えかもしれません.この記事では、まさにそれを見ていきます。最初に、Android に Edge ブラウザーをインストールする方法について説明し、次に Edge ブラウザーを最大限に活用する方法について説明します。 それでは始めましょう。 Android に Edge をインストールする方法 Google、Facebo

  2. Android で貴重な写真を非表示にする方法

    写真やビデオを隠したいと思ったことはありませんか?一部の思い出は共有することを意図していないと感じたことがありますか?または、家族や友人があなたの携帯電話を手に取り、あなたの写真やビデオを見ているという事実はありますか?そう感じているのはあなただけではありません!真実は、誰もが秘密を持っていて、それを維持したいということです.そのために必要なのは、Android スマートフォンのアプリだけです。この記事では、Android で写真を非表示にする方法について説明します。 写真を秘密に:ギャラリーの写真とビデオを非表示にする 私が最近発見したすばらしいアプリの 1 つは、Systweak Sof