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);
        //레이아웃이 완료되면 첫 번째 소그래이드와 두 번째 그래이드 사이의 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) {
     //두 번째 Pager에 슬라이드할 때, positionOffset 비율이 0이 되고, position이1따라서 position을 추가해야 합니다;*mPaintDis
     int leftMargin = (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);
     //작은 원형 점  하나의 작은 회색 점은 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){
       //추가된 작은 원형 점의 개수가 하나를 초과하면 현재 작은 원형 점의 왼쪽 간격을 설정합니다10dp;
        params.leftMargin=10;
      }
     //작은 회색 점의 너비와 높이를 내용을 포함하여 설정합니다
      pointView.setLayoutParams(params);
      //작은 회색 점을 LinearLayout에 추가합니다
      llContainer.addView(pointView);
    }
   }
 class GuideAdapter extends PagerAdapter{
    //항목의 개수
    @Override
    public int getCount() {
       return mImageViewList.size();
    }
    @Override
     public boolean isViewFromObject(View view, Object object) {
       return view == object;
    }
    //초기화 항목 레이아웃
     @Override
     public Object instantiateItem(ViewGroup container, int position) {
       ImageView view = mImageViewList.get(position);
      container.addView(view);
      return view;
    }
    //item 소멸
    @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와 함께 움직입니다.

위에는 세 개의 작은 회색 점이 있으며, 그 위에는 작은 빨간 점이 있으며, 첫 번째 작은 회색 점과 두 번째 작은 회색 점 사이의 거리를 계산하여 ViewPager의 슬라이딩 리스너를 설정하고, 빨간 점이 pager와 함께 움직이도록 할 수 있습니다(변경되는 것은 부모 컨트롤의 내쪽 여백입니다).

작은 회색 점 사이의 거리를 계산할 때 주의해야 할 것은, 레이아웃 위치가 확정된 후에야 작은 회색 점 사이의 거리를 얻을 수 있습니다(화면 생성 과정의 measure)->layout(위치 설정)->draw(activity의 onCreate 메서드 실행이 끝난 후에만 이 프로세스가 실행됩니다) 그래서 레이아웃의 리스너를 설정해야 합니다:

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

그런 다음, 작은 회색 점 사이의 거리를 얻습니다:

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

이 코드를 주의해야 합니다:
int leftMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;

positionOffset은 현재 슬라이딩의 퍼센트를 나타내며, 두 번째 페이지로 진입할 때 값은 0입니다.
position은 현재 몇 번째 페이지인지를 나타내며, 0부터 시작하므로 두 번째 페이지로 슬라이딩할 때 mPaintDis*0+1*mPaintDis;

PS: 사고를 요약하다:

  1페이지는 ViewPager + Button + RelativeLayout(LinearLayout + TextView)
  2LinearLayout에 소금점이 들어갑니다. 소금점의 개수는 ViewPager의 개수에 따라 결정되며, 따라서 LinearLayout에 소금점을 추가할 때는 ViewPager의 이미지 자원을 집합에 추가하는 것과 동시에 합니다.
  3그런 다음 빨간점은 TextView이며, 상대 레이아웃의 이유로, 빨간점의 초기 위치는 소금점의 첫 번째 점과 일치합니다.
  4그런 다음 ViewPager의 슬라이딩 이벤트를 감지하고, 첫 번째와 두 번째 소금점의 왼쪽에서 LinearLayout의 왼쪽까지의 간격 차이를 계산하여 빨간점의 위치를 이동시킵니다. 그러나 위치를 확인하는 것은 레이아웃의 위치가 이미 정해져 있어야 하므로, 레이아웃이 이미 정해졌는지 감지하고, 정해진 후 위치 차이를 계산해야 합니다.

이것이 이 문서의 전부입니다. 많은 도움이 되었기를 바랍니다. 또한, 나락 강의를 많이 지지해 주세요.

고지사항: 이 문서의 내용은 인터넷에서 가져왔으며, 원 저작자의 소유물로, 인터넷 사용자가 자발적으로 기여하고 자체적으로 업로드한 것이며, 이 사이트는 소유권을 가지지 않으며, 인공적인 편집 처리를 하지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 침해가 의심되는 내용을 발견하면 이메일을 notice#w로 보내 주세요.3codebox.com에 이메일을 보내면 (#을 @으로 변경하여 보내세요) 신고를 하고 관련 증거를 제공하면, 실제로 확인되면 이 사이트는 즉시 저작권 침해 내용을 삭제할 것입니다.

좋아하는 것