Android高仿微信5.2.1主インターフェースとメッセージのリマインダ


久しぶりにブログを更新しました。最近は会社のプロジェクトをやっています。これも私が接する最初の正式プロジェクトです。プロジェクトの検証を通して、自分が一年間の知識を蓄積してきたのか、それともまだまだ足りないのかを発見しました。最も重要な点:まめに手を下す。最近憧れの授業ネットの動画を見つけましたが、なんとすべてハイビジョン無料です。しかも乾物がいっぱい!余暇の時間を使ってビデオの中の大神さんの説明に従って多くの知識を学びました。これらの小さいデモを皆さんと共有します。もちろん、いくつかの最適化をしました。コードとビデオの中には違いがありますが、機能は完全に実現できます。
これは5.2.1バージョンを模した表示画面です。
这里写图片描述
機能及び実現構想概要
主な機能は簡単です。
1、上にはユーザー定義のタイトルバーがあります。
2、下はチャット、発見、通信記録タブです。
3、指が滑る時、文字の下の青いindicatorはスライドに従うことができます。
4、チャットの右側に、未読メッセージの赤い点々があります。
ユーザー定義のタイトルバーはLineear Layoutであり、同時にシステムが持っているTitleBar(またはアクションBar)を隠します。
タブなので、自然とフラジャメンションを思い出しました。
指をスライドさせることができます。明らかに黒いエリアはViewPagerです。データソースはFragmentのセットです。そしてFragment PagerAdapterを通じて管理します。
青いindicatorをタブのスライドに合わせてスライドさせるには、Viewer Pagerのためにモニターを設定し、そのフィードバック値に応じてIndicatorのmarking Left属性値を制御することで、この効果を実現します。
最後にメッセージが提示された小さい円点はBadgeViewであり、これは第三者のオープンソースコントロールである。
メインレイアウト
MainActivityレイアウトは以下の通りです。まずカスタムTitleBarです。

<!-- top1.xml -->

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

 android:layout_width="match_parent"
 android:layout_height="50dp"
 android:background="@drawable/topone_bg"
 android:paddingLeft="12dp"
 android:paddingRight="12dp">

 <LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_centerVertical="true"
  android:gravity="center"
  android:orientation="horizontal">

  <ImageView
   android:layout_width="30dp"
   android:layout_height="30dp"
   android:background="@drawable/actionbar_icon" />

  <TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginLeft="12dp"
   android:text="  "
   android:textColor="#D3D3D3"
   android:textSize="18sp" />
 </LinearLayout>

 <LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_alignParentRight="true"
  android:layout_centerVertical="true"
  android:orientation="horizontal">


  <ImageView
   android:layout_width="30dp"
   android:layout_height="30dp"
   android:background="@drawable/actionbar_search_icon" />

  <ImageView
   android:layout_width="30dp"
   android:layout_height="30dp"
   android:background="@drawable/actionbar_add_icon" />

  <ImageView
   android:layout_width="30dp"
   android:layout_height="30dp"
   android:background="@drawable/actionbar_more_icon" />


 </LinearLayout>


</RelativeLayout>

効果は以下の通りです。
这里写图片描述
次は3つのタブのレイアウトです。

<!-- top2.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="40dp"
 android:background="#EEEEEE"
 android:orientation="vertical">

 <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="37dp"
  android:orientation="horizontal">

  <LinearLayout
   android:id="@+id/ll_chat"
   android:layout_width="0dp"
   android:layout_height="match_parent"
   android:layout_weight="1"
   android:gravity="center"
   android:orientation="horizontal">

   <TextView
    android:id="@+id/tv_tab_chat"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"

    android:layout_gravity="center"
    android:text="  "
    android:textColor="#008000"
    android:textSize="16sp" />


  </LinearLayout>

  <LinearLayout
   android:layout_width="0dp"
   android:layout_height="match_parent"
   android:layout_weight="1"
   android:gravity="center">

   <TextView
    android:id="@+id/tv_tab_discover"
    android:layout_width="wrap_content"

    android:layout_height="wrap_content"
    android:text="  "
    android:textColor="@android:color/black"
    android:textSize="16sp" />


  </LinearLayout>

  <LinearLayout
   android:layout_width="0dp"
   android:layout_height="match_parent"
   android:layout_weight="1"
   android:gravity="center">

   <TextView
    android:id="@+id/tv_tab_contacts"

    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="   "
    android:textColor="@android:color/black"
    android:textSize="16sp" />


  </LinearLayout>

 </LinearLayout>

 <ImageView
  android:id="@+id/iv_tab_line"
  android:layout_width="100dp"
  android:layout_height="3dp"
  android:background="@drawable/tabline" />

</LinearLayout>

効果は以下の通りです

Indicatorはコードにその長さを動的に設定する必要があるので、xmlには任意の値を付すことができます。
最後にtop 1.xml、top 2.xmlをメインレイアウトに追加し、メインレイアウトにViewer Pagerを導入します。

<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context="com.demo.lenovo.myapplication.MainActivity">

 <include layout="@layout/top1" />

 <include layout="@layout/top2" />

 <android.support.v4.view.ViewPager
  android:id="@+id/vp_content"
  android:layout_width="match_parent"
  android:layout_height="0dp"
  android:layout_weight="1" />
</LinearLayout>


効果は以下の通りです

注:ActivityがアクションBarActivityに引き継がれるように、set ContentView()メソッドの前にタイトルバーを呼び出しても良いです。AppComppactActivityに継承すれば、Android Mainfestでも大丈夫です。
のアプリタグに設定されているテーマは、requestWindowFeature(Window.FEATURE_NO_TITLE);であり、隠しタイトルバーの目的を実現することもできます。
Frangement Pager Adapterを使って、Viewer Pagerに適合するデータです。
MainActivity.javaでは、フラジャメント・PagerAdapterロジックを追加します。

 private FragmentPagerAdapter adapter;
 private List<Fragment> mData;

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    initView();

initView()では、Fragmentを初期化し、一度にFragmentのインスタンスをListにロードし、次に、Frangement PagerAdapterを初期化する際にListのデータを管理する。最後にViewer Pagerを呼び出すsetAdapter方法は、FrangentPager Adapterのインスタンスを着信します。

 mData = new ArrayList<>();
    mData.add(new ChatFragment());
    mData.add(new DiscoverFragment());
    mData.add(new ContactsFragment());
    adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
      @Override
      public Fragment getItem(int position) {
        return mData.get(position);
      }

      @Override
      public int getCount() {
        return mData.size();
      }
    };
    vp_content.setAdapter(adapter);

スライド時のフォントの色の変化を設定します。
この機能を実現するためには、Viewer PagerにsetOnPage Listenerを設定し、OnPageChange Listenerインターフェースのコールバック方法onPagerSelected(int position)を設定し、現在何ページ目にスライドしているかをモニターする必要があります。

@Override
      public void onPageSelected(int position) {
        Log.e(TAG, "onPageSelected: " + position);
        resetTextViewColor();
        switch (position) {
          case 0:       
          addBadgeView();  tv_tab_chat.setTextColor(Color.parseColor("#008000"));
            break;

          case 1:
            tv_tab_discover.setTextColor(Color.parseColor("#008000"));
            break;

          case 2:
            tv_tab_contacts.setTextColor(Color.parseColor("#008000"));
            break;
        }

      }

//                 
 private void resetTextViewColor() {
    tv_tab_contacts.setTextColor(Color.BLACK);
    tv_tab_chat.setTextColor(Color.BLACK);
    tv_tab_discover.setTextColor(Color.BLACK);

BadgeViewを追加
addBadgeView();方法ではまずBadgeViewが空かどうかを判断します。空でなければ、まずそれを除去して、新しいBadgeViewを追加します。コードは以下の通りです。

 private void addBadgeView()
 {
 if (mBadgeView != null) {
              ll_chat.removeView(mBadgeView);
            }
            mBadgeView = new BadgeView(MainActivity.this);
            ll_chat.addView(mBadgeView);
            mBadgeView.setBadgeCount(9);


}

スライド時のフォントの色の変化を設定します。
この機能を実現するためには、Viewer PagerにsetOnPage Listenerを設定し、OnPageChange Listenerインターフェースのコールバック方法onPagerSelected(int position)を設定し、現在何ページ目にスライドしているかをモニターする必要があります。

@Override
      public void onPageSelected(int position) {
        Log.e(TAG, "onPageSelected: " + position);
        resetTextViewColor();
        switch (position) {
          case 0:       
          addBadgeView();  tv_tab_chat.setTextColor(Color.parseColor("#008000"));
            break;

          case 1:
            tv_tab_discover.setTextColor(Color.parseColor("#008000"));
            break;

          case 2:
            tv_tab_contacts.setTextColor(Color.parseColor("#008000"));
            break;
        }

      }

//                 
 private void resetTextViewColor() {
    tv_tab_contacts.setTextColor(Color.BLACK);
    tv_tab_chat.setTextColor(Color.BLACK);
    tv_tab_discover.setTextColor(Color.BLACK);

BadgeViewを追加
addBadgeView();方法ではまずBadgeViewが空かどうかを判断します。空でなければ、まずそれを除去して、新しいBadgeViewを追加します。コードは以下の通りです。

 private void addBadgeView()
 {
 if (mBadgeView != null) {
              ll_chat.removeView(mBadgeView);
            }
            mBadgeView = new BadgeView(MainActivity.this);
            ll_chat.addView(mBadgeView);
            mBadgeView.setBadgeCount(9);


}

indicatorの滑り
このIndicatorが指のスライドに従って従う効果を実現するためには、OnPageChange Listenerインターフェース内のonPageScrroled()メソッドに論理を作成する必要があり、この方法の文書は以下の通りである。

ここで、最初のパラメータpositionは、第0ページから第1ページにスライドすると、positionは0になります。手を放した後、最初のページにスライドします。positionは1になります。第2のパラメータpositionOffsetはスライドの割合を表します。取得範囲は0-1、最後のパラメータpositionOffset Pixelsはピクセルのスライド数を表します。
以下は0-->1ページから印刷されたロゴです。
这里写图片描述
1->>2ページから印刷されたロゴ:
这里写图片描述
2->>1ページから印刷されたロゴ:
这里写图片描述
最後に、IndicatorのmagingLeftは、(positionOffset)*1/3に基づいて設定されてもよい。
まず、画面幅の1/3の幅をIndicatorに設定します。

 WindowManager manager = getWindow().getWindowManager();
    Display display = manager.getDefaultDisplay();
    DisplayMetrics outMetrics = new DisplayMetrics();
    display.getMetrics(outMetrics);
    mScreenOneThird = outMetrics.widthPixels / 3;

ここで、int型パラメータmScrenOneThirdの単位は画素pxである。
Indicatorに設定:

LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) iv_tab_line.getLayoutParams();
    lp.width = mScreenOneThird;
    iv_tab_line.setLayoutParams(lp);

最終的にonPageScrrolled方法でIndicatorのmargingLeft属性を動的に変化させる:

@Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) iv_tab_line.getLayoutParams();
        lp.leftMargin = (int) ((positionOffset * mScreenOneThird) + (mScreenOneThird * position));
        iv_tab_line.setLayoutParams(lp);

最終効果が実現できます。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。