English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Androidで華やかなガイドインターフェースを描画

まず開発する画面を見てみましょう(3枚の画像があって、最後にスライドすると「体験開始」のボタンが現れ、下の赤い点も一緒にスライドします):


まずレイアウトファイルを見てみましょう:

 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@"+id/activity_guide"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context="com.coderwei.a71_zhbj.activity.GuideActivity">
   <android.support.v4.view.ViewPager
     android:id="@"+id/vp_guide"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     />
   <Button
     android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="70dp"
    android:padding="10dp"
    android:id="@"+id/start_btn"
    android:textColor="#f1eaea"
   android:background="#e71616"
   android:text="开始体验"
   android:visibility="invisible"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content" />
  <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="30dp">
   <LinearLayout
     android:id="@"+id/ll_container"
     android:layout_width="wrap_content"
    android:layout_height="wrap_content">
   </LinearLayout>
  <ImageView
    android:id="@"+id/iv_red"
   android:src="@drawable/shap_red"
   android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
 </RelativeLayout>
 </RelativeLayout>

それでは、コードの次です:

public class GuideActivity extends Activity {
   private ViewPager mViewPager;
   private int[] mImageIds = new int[]{R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3};
   private ArrayList<ImageView> mImageViewList;
   private LinearLayout llContainer;
   private ImageView ivRedPoint;
   private int mPaintDis;
   private Button start_btn;
  @Override
 protected void onCreate(Bundle savedInstanceState) {
   uper.onCreate(savedInstanceState);
   requestWindowFeature(Window.FEATURE_NO_TITLE);
   setContentView(R.layout.activity_guide);
   mViewPager = (ViewPager)findViewById(R.id.vp_guide);
   llContainer = (LinearLayout) findViewById(R.id.ll_container);
   ivRedPoint = (ImageView) findViewById(R.id.iv_red);
   start_btn = (Button) findViewById(R.id.start_btn);
   initData();
   GuideAdapter adapter = new GuideAdapter();
   mViewPager.setAdapter(adapter);
   //レイアウトが完了したかどうかを監視し、レイアウトの位置が確定したかどうかを監視
    ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
       //重複のカールバックを避けるため、互換性のために古い方法を使用しています
        ivRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        //レイアウトが完了したら、最初の小さな灰色のポイントと第2の間のleftの距離を取得
        mPaintDis =  llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft();
        System.out.println("距離:");+mPaintDis);
      }
   });
  //ViewPagerのPagerスライドリスナー
  mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
     //スライド中のカールバック
     @Override
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
     //第2つのPagerにスライドするとき、positionOffsetパーセンテージは0に、positionは1、そのため後でpositionを追加する必要があります*mPaintDis
     int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;
     //親レイアウトのウィジェットにleftMarginの余白を設定
      RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)ivRedPoint.getLayoutParams();
     params.leftMargin = letfMargin;
     ivRedPoint.setLayoutParams(params);
     }
     @Override
      public void onPageSelected(int position) {
        System.out.println("position:");+position);
        if (position==mImageViewList.size())-1{
         start_btn.setVisibility(View.VISIBLE);
       }
     }
     @Override
      public void onPageScrollStateChanged(int state) {
       System.out.println("state:");+state);
      }
    });
  }
  private void initData(){
    mImageViewList = new ArrayList<>();
    for (int i=0; i<mImageIds.length; i++{
      //ImageViewを作成し、mImgaeViewIdsを入れています
      ImageView view = new ImageView(this);
      view.setBackgroundResource(mImageIds[i]);
      //ImageViewのリストに追加します
      mImageViewList.add(view);
     //小さな円点  1つの小さな灰色の点はImageViewです
     ImageView pointView = new ImageView(this);
      pointView.setImageResource(R.drawable.shape);
      //レイアウトパラメータを初期化します、親コンテナが誰なら、そのレイアウトパラメータを初期化します
     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
     if (i>0){
       //追加された小さな円の数が1個を超えたら、現在の小さな円の左マージンを設定します10dp;
        params.leftMargin=10;
      }
     //小さな灰色の点の幅と高さを内容に合わせて設定します
      pointView.setLayoutParams(params);
      //小さな灰色の点をLinearLayoutに追加します
      llContainer.addView(pointView);
    }
   }
 class GuideAdapter extends PagerAdapter{
    //itemの数
    @Override
    public int getCount() {
       return mImageViewList.size();
    }
    @Override
     public boolean isViewFromObject(View view, Object object) {
       return view == object;
    }
    //初期化itemレイアウト
     @Override
     public Object instantiateItem(ViewGroup container, int position) {
       ImageView view = mImageViewList.get(position);
      container.addView(view);
      return view;
    }
    //アイテムを破棄します
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
      container.removeView((View)object);
    }
  }
 } 

小さな灰色の点:

<?xml version="1.0" encoding="utf-8"?>
<shape
   android:shape="oval"
   xmlns:android="http://schemas.android.com/apk/res/android">
   <!--小さな灰色の点-->
   <solid android:color="#cccccc"/>
   <size android:width="10dp" android:height="10dp"/>
</shape>

赤い点:

<?xml version="1.0" encoding="utf-8"?>
 <shape
   android:shape="oval"
   xmlns:android="http://schemas.android.com/apk/res/android">
   <solid android:color="#f00"/>
   <size android:width="10dp" android:height="10dp"/>
 </shape>

ViewPageは非常に単純で、前のブログでも詳細に紹介されていますが、ここでは詳しく説明しません。主に赤い点がPagerと一緒に動くことです。

上記は3つの小さな灰色の点で構成されており、その上に小さな赤い点があります。最初の小さな灰色の点と第2の小さな灰色の点との距離を計算することで、ViewPagerのスライドリスナーを設定し、赤い点をpagerと一緒に動かすことができます(変更されるのは親コントロールの内側マージンです)。

小さな灰色の点との距離を計算する際には、レイアウト位置が確定した後に小さな灰色の点との距離を得ることが必要です(UIの生成プロセス measure->layout(位置を確定)->draw(activityのonCreateメソッドが終了した後にこのプロセスが実行されます),のでlayoutのリスナーを設定する必要があります:

ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()

それから小さな灰色の点との距離:

mPaintDis =  llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft();

必要に注意的是このコード:
int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;

positionOffsetは現在のスライドのパーセンテージを表し、2番目のpageに入ったとき、値は0です。
positionは現在のpageのインデックスを表し、0から始まるため、2番目のpageにスライドした場合、mPaintDis*0+1*mPaintDis;

PS:考え方の要約:

  1、ページはViewPagerで構成されています。 + Button + RelativeLayout(LinearLayout + 、TextView)で構成されています。
  2、LinearLayoutには小さな灰色の点が配置されており、小さな灰色の点の数はViewPagerの数に依存します。したがって、LinearLayoutに小さな灰色の点を追加する際には、ViewPagerの画像リソースをコレクションに追加する際と同時に行われます。
  3、次に赤い点はTextViewであり、レイアウトの関係で、赤い点の初期位置は小さな灰色の点の最初の点と重なります。
  4、次にViewPagerのスライドイベントをリスニングし、最初の小さな灰色の点と二つ目の小さな灰色の点の左端からLinearLayoutの左端までのマージン差を計算して、赤い点の位置を移動させますが、位置を確認する際にはレイアウトの位置が既に確定していることを確認する必要があります。したがって、レイアウトが既に確定しているかどうかをリスニングし、確定した後に位置差を計算する必要があります。

これで本文のすべての内容が終わりました。皆様の学習に役立つことを願っています。また、呐喊教程を多くの皆様にサポートしていただけると嬉しいです。

声明:本文の内容はインターネットから取得しており、著作権者は所有者であり、インターネットユーザーにより自発的に貢献し、アップロードされています。本サイトは所有権を有しておらず、人工編集は行われていません。著作権侵害を疑う内容が見つかった場合は、notice#wまでメールをお送りください。3codebox.com(メール送信時は、#を@に変更してください)で通報してください。関連する証拠を提供していただければ、本サイトは直ちに侵害疑いのコンテンツを削除します。

おすすめ