安卓学习记录--引导页底部跟随小圆点

本文介绍如何在Android应用中实现滑动时下方小圆点跟随的效果。通过使用ViewPager展示图片,并配合LinearLayout布局实现小圆点指示器,再利用ViewTreeObserver计算小圆点间的距离,最终达到平滑切换指示器的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次发博客,希望给刚学的同学提供一点点帮助,同时也是记录自己的学习成果和成长历程,开车….呸,开始吧。

效果如下

滑动屏幕下方小圆点跟随移动
滑动屏幕下方小圆点跟随移动

布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_guild"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v4.view.ViewPager>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="30dp">
        <LinearLayout
            android:id="@+id/ll_point"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            >
        </LinearLayout>
        <View
            android:id="@+id/red_point"
            android:layout_width="10dp"
            android:layout_height="10dp"
            android:background="@drawable/shape_point_red"
            ></View>
    </RelativeLayout>

</RelativeLayout>

三个小灰点用的是线性布局,因为小红点是覆盖在小灰点上方,所以外面套一个相对布局。

先给ViewPager填充图片

ArrayList<View> ivList=new ArrayList<View>();

for(int i=0;i<imageIds.length;i++){
    ImageView iv= new ImageView(this);
    iv.setBackgroundResource(imageIds[i]);
    ivList.add(iv);
}

在给线性布局充填充小圆点

LinearLayout llPoint=(LinearLayout) findViewById(R.id.ll_point);

for(int i=0;i<imageIds.length;i++){
View point=new View(this);    point.setBackgroundResource(R.drawable.shape_point_gray);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(15,15);
if(i>0){
    params.leftMargin=20;
}
point.setLayoutParams(params);
llPoint.addView(point);

接下来就是在ViewPager的事件监听中,计算滑动移动的距离,和给红点设置参数了

注意:计算两个点之间的距离时,要在Layout加载完了之后才能计算,不然得到的是0,因为在onCreate中计算的话,这时还没有执行测量和绘制Layout的方法(measure()和layout()),可以让灰点绘制完后计算,具体做法如下:

llPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        length=llPoint.getChildAt(1).getLeft()-llPoint.getChildAt(0).getLeft();
    }
});
贴上具体实现代码

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import java.util.ArrayList;


public class GuildActivity extends Activity {
    private static final int[] imageIds=new int[]{
            R.drawable.shit_1,
            R.drawable.shit_2,
            R.drawable.shit_3
    };
    private ViewPager vpGuild;
    private LinearLayout llPoint;
    private ArrayList<View> ivList;
    private View redPoint;
    private static int length;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_guild);
        initParam();
        initPage();
        initEvent();
    }

    private void initEvent() {
        vpGuild.setAdapter(new GuildAdpter());
        vpGuild.setOnPageChangeListener(new PageChange());
        llPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                length=llPoint.getChildAt(1).getLeft()-llPoint.getChildAt(0).getLeft();
            }
        });
    }

    private void initParam() {
        vpGuild= (ViewPager) findViewById(R.id.vp_guild);
        llPoint=  (LinearLayout) findViewById(R.id.ll_point);
        redPoint=findViewById(R.id.red_point);
    }

    public void initPage(){
        ivList=new ArrayList<View>();
        for(int i=0;i<imageIds.length;i++){
            ImageView iv= new ImageView(this);
            iv.setBackgroundResource(imageIds[i]);
            ivList.add(iv);
        }
        //初始化小圆点
        for(int i=0;i<imageIds.length;i++){
            View point=new View(this);
            point.setBackgroundResource(R.drawable.shape_point_gray);
            LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(15,15);
            if(i>0){
                params.leftMargin=20;
            }
            point.setLayoutParams(params);
            llPoint.addView(point);
        }


    }

    class PageChange implements ViewPager.OnPageChangeListener{

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            float distance=length*(position+positionOffset);
            RelativeLayout.LayoutParams params= (RelativeLayout.LayoutParams) redPoint.getLayoutParams();
            params.leftMargin=Math.round(distance);
            redPoint.setLayoutParams(params);
        }

        @Override
        public void onPageSelected(int position) {  //当前页面的页数

        }

        @Override
        public void onPageScrollStateChanged(int state) {
        //1:拖动状态 2:安放 3:空闲
        }
    }

    class GuildAdpter extends PagerAdapter{

        @Override
        public int getCount() {
            return ivList.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(ivList.get(position));
            return ivList.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(ivList.get(position));
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值