Android–ViewPager实现滑动广告
来介绍一下如何去做一个滑动广告
xml代码:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="180dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#44000000"
android:layout_alignBottom="@+id/viewpager"
android:padding="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="美国队长3"
android:textColor="#ffffff"
android:layout_gravity="center"
android:id="@+id/tv_name"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:id="@+id/ll_point"/>
</LinearLayout>
</RelativeLayout>
首先,因为我们的广告底部是一行文字和点;所以我们用采用整体使用相对布局,之后有一点要注意的是:Viewpager是v4包里的,还有一点就是:高度的设置尽量别设置“自适应”,因为有可能不显示。所以我们指定一个高度(180dp)。
之后,我们的广告下方有导航点和文字,用一个线性布局将其放在指定viewpager的下方,颜色为:灰色;
Java代码:
先把整段代码发出来,再将每块代码逐一分析:
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private LinearLayout ll_point;
private TextView tv_name;
private ArrayList<ImageView> pictures;
private final int[] imageId = {R.drawable.a, R.drawable.b};
private final String[] imageName={"图片a","图片b"};
/**
* 上一次高亮的位置
*/
private int prePosition=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
ll_point = (LinearLayout) findViewById(R.id.ll_point);
tv_name = (TextView) findViewById(R.id.tv_name);
pictures = new ArrayList<>();
for (int i = 0; i < imageId.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(imageId[i]);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(8,8);
//将图片添加到集合
pictures.add(imageView);
//添加点
ImageView point =new ImageView(this);
point.setBackgroundResource(R.drawable.point_selector);
if(i==0){
point.setEnabled(true);
}else{
point.setEnabled(false);
params.leftMargin=8;
}
point.setLayoutParams(params);
ll_point.addView(point);
}
//设置适配器(PagerAdaptor)-item布局-绑定数据
viewPager.setAdapter(new MyPagerAdaptor());
//设置监听viewPager的改变
viewPager.addOnPageChangeListener(new MyOnPageChangeListener());
}
class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {
/**
*当页面滑动的时候回调这个方法
* @param position 当前页面的位置
* @param positionOffset 滑动页面的百分比
* @param positionOffsetPixels 在屏幕上滑动的像素
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//设置对应文本信息
tv_name.setText(imageName[position]);
//把上一个高亮的位置设置为默认--灰色
ll_point.getChildAt(prePosition).setEnabled(false);
//当前的设置为高亮--红色
ll_point.getChildAt(position).setEnabled(true);
prePosition=position;
}
/**
*当某个页面呗选中了回调
* @param position 被选中页面的位置
*/
@Override
public void onPageSelected(int position) {
}
/**
* 当页面滑动状态变化的时候回调这个方法
* 静止-》滑动 滑动-》静止 静止-》拖拽
* @param state
*/
@Override
public void onPageScrollStateChanged(int state) {
}
}
class MyPagerAdaptor extends PagerAdapter {
/**
* @return 得到图片的总数
*/
@Override
public int getCount() {
return pictures.size();
}
/**
*相当于getView方法
* @param container Viewpager自身
* @param position 当前实例化位置
* @return
*/
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
ImageView imageView=pictures.get(position);
container.addView(imageView);//添加到Viewpager中
return imageView;
}
/***
*比较View和Oject是否同一实例
* @param view 页面
* @param object 这个方法instantiateItem返回的结果
* @return
*/
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view==object;
}
/**
*释放资源
* @param container Viewpager
* @param position 要释放的位置
* @param object 要释放的页面
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//super.destroyItem(container, position, object);
container.removeView((View)object);
}
}
}
第一段代码,将各个要用到的对象实例化:
private ViewPager viewPager;
private LinearLayout ll_point;
private TextView tv_name;
private ArrayList<ImageView> pictures;//图片集合
private final int[] imageId = {R.drawable.a, R.drawable.b};
private final String[] imageName={"图片a","图片b"};
/**
* 上一次高亮的位置
*/
private int prePosition=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
ll_point = (LinearLayout) findViewById(R.id.ll_point);
tv_name = (TextView) findViewById(R.id.tv_name);
pictures = new ArrayList<>();
(ArrayList:不安全,但效率高)
for循环内容解释:
图片的个数
for (int i = 0; i < imageId.length; i++)
创建图片视图进行实例化,为其设置背景(如果使用src的话,可能填充不全)
将每张视图添加进集合。
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(imageId[i]);
//LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(8,8);
//将图片添加到集合
pictures.add(imageView);
为其viewPager设置适配器
viewPager.setAdapter(new MyPagerAdaptor());
class MyPagerAdaptor extends PagerAdapter {
/**
* @return 得到图片的总数
*/
@Override
public int getCount() {
return pictures.size();
}
/**
*相当于getView方法
* @param container Viewpager自身
* @param position 当前实例化位置
* @return
*/
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
ImageView imageView=pictures.get(position);
container.addView(imageView);//添加到Viewpager中
return imageView;
}
/***
*比较View和Oject是否同一实例
* @param view 页面
* @param object 这个方法instantiateItem返回的结果
* @return
*/
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view==object;
}
/**
*释放资源
* @param container Viewpager
* @param position 要释放的位置
* @param object 要释放的页面
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//super.destroyItem(container, position, object);
container.removeView((View)object);
}
}
(接下来内容为个人理解)
讲一下适配器,我个人理解是:我们是为一个控件设置适配器,而不是为了一个集合设置适配器,所以为viewPager设置适配器,而不是pictures。当然,目的是将图片集合放进viewpager里面。
第一个方法:去获得图片的总数,所以是pictures.size();
第二个方法:(看看上面的注释大概能明白吧,不用解释太多)
第三个方法:(略,看上面注释,之后明白点再讲的详细的,它是就跟对比)
第四个方法:释放资源。首先,我们要明白,首次加载时,是加载了第一张和第二张图片,最多加载三个。也就是说:若有5张图片,首先加载1,2张图片;之后当我们活动时,加载第3张图片,当我们滑动至第3张时,我们将加载第4张,而释放掉第1张图片。
上面的代码完成就可以做一个简单的滑动广告,
(不含有下面的导航点,和文字随内容变化)
接下来解释关于导航点的和文字随内容变化的代码:
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(8,8);
//添加点
ImageView point =new ImageView(this);
point.setBackgroundResource(R.drawable.point_selector);
if(i==0){
point.setEnabled(true);
}else{
point.setEnabled(false);
params.leftMargin=8;
}
point.setLayoutParams(params);//之后解释
ll_point.addView(point);
因为“点”也是图片,所以创建一个point对象进行实例化。
第二行代码为设置点的样式。
if语句:因为首次加载时第0号位的图片,所以将第0号位的点设为 “true”,表示当前图片。
else:否则,除了首个点以外,其余的点 距离 左边的点为8(单位…未知),且为false状态
之后,为其viewPager设置滑动的监听:
//设置监听viewPager的改变
viewPager.addOnPageChangeListener(new MyOnPageChangeListener());
因为我们不会用到第二三个方法,具体的参数看上面的代码,这里只写第一个方法的内容。
/**
*当页面滑动的时候回调这个方法
* @param position 当前页面的位置
* @param positionOffset 滑动页面的百分比
* @param positionOffsetPixels 在屏幕上滑动的像素
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//设置对应文本信息
tv_name.setText(imageName[position]);
//把上一个高亮的位置设置为默认--灰色
ll_point.getChildAt(prePosition).setEnabled(false);
//当前的设置为高亮--红色
ll_point.getChildAt(position).setEnabled(true);
prePosition=position;
}
tv_name:每个图片对应的文字
将其文本设置为数组的对应位置的文字。
prePositiond的用途:标记上一个图片对应的位置。
(其余的理一理就明白了)
point(点)的样式代码:
point_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:drawable="@drawable/point_normal"/>
<item android:state_enabled="true" android:drawable="@drawable/point_press"/>
</selector>
point_press.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<size
android:width="8dp"
android:height="8dp"/>
<solid android:color="#ff0000" />
</shape>
point_normal.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<size
android:height="8dp"
android:width="8dp"/>
<solid android:color="#44000000"/>
</shape>
好了,上面有写内容还需要补充,如果有大佬看到了,望能指点我不明之处,有错误的,也希望可以跟我给我留言,谢谢。