上一节我们已经写好了自定义的view并且成功运行了,这一节我们把数据绑定进自定义的view
首先我们给自定义view中的几个控件设定好id并且在自定义的java类中进行声明和绑定
package com.example.viewpager.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;
import com.example.viewpager.R;
public class LooperPager extends LinearLayout {
private ViewPager viewPager;
private TextView textView;
private LinearLayout linearLayout;
public LooperPager(Context context) {
this(context,null);
}
public LooperPager(Context context, @Nullable AttributeSet attrs) {
this(context,attrs,0);
}
/**
* java必须有一个声明super的构造器,而且必须在开头,所以其他构造器声明的this,、
* 所以无论使用其他哪个构造器都必须要调用该构造器
* @param context
* @param attrs
* @param defStyleAttr
*/
public LooperPager(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//自定义布局绑定当前类,this:当前类,ture:确定绑定
LayoutInflater.from(context).inflate(R.layout.looper_pager,this,true);
inti();
}
/**
*
*/
private void inti() {
intiView();
}
/**
* 设置数据的方法
*/
public void setData(){
}
/**
* 加载view的方法
*/
private void intiView() {
viewPager = findViewById(R.id.viewPager);
textView = findViewById(R.id.looper_title_tv);
linearLayout = findViewById(R.id.looper_point_container_lv);
}
}
绑定好之后就是设置数据的方法
首先是设置标题的方法,我们给ViewPager写一个监听,三个状态:滑动中,停止和状态改变,我们在监听停止状态的方法内获得标题,用一个自制的强制获得String类型的接口的实例来获得当前停止状态下页面的标题来作为标题(有点绕哈)。
然后是设置ViewPager,这里我们直接让外部填一个适配器类型的数据就行,就能设置ViewPager的数据了
package com.example.viewpager.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.example.viewpager.R;
public class LooperPager extends LinearLayout {
private ViewPager viewPager;
private TextView textView;
private LinearLayout linearLayout;
private BindTitleLisener bindTitleLisener = null;//标题,先设为空
public LooperPager(Context context) {
this(context,null);
}
public LooperPager(Context context, @Nullable AttributeSet attrs) {
this(context,attrs,0);
}
/**
* java必须有一个声明super的构造器,而且必须在开头,所以其他构造器声明的this,、
* 所以无论使用其他哪个构造器都必须要调用该构造器
* @param context
* @param attrs
* @param defStyleAttr
*/
public LooperPager(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//自定义布局绑定当前类,this:当前类,ture:确定绑定
LayoutInflater.from(context).inflate(R.layout.looper_pager,this,true);
inti();
}
/**
*
*/
private void inti() {
intiView();
initEven();
}
/**
* 对页面进行滑动监听的方法
*/
private void initEven() {
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
//切换的回调方法
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
//切换停止的回调方法
public void onPageSelected(int position) {
//当页面切换停止后获得标题
//如果标题不是空的,就设定标题为当前停止的页面标题里的数据
if (bindTitleLisener != null){
textView.setText(bindTitleLisener.getTitle(position));
}
}
@Override
//状态改变的回调方法
public void onPageScrollStateChanged(int state) {
}
});
}
/**
* 获得标题的接口,里面有一个获得标题的抽象方法
*/
public interface BindTitleLisener{
String getTitle(int position);
}
/**
* 设置数据的方法
*/
public void setData(PagerAdapter adapter,BindTitleLisener lisener){
bindTitleLisener = lisener;
viewPager.setAdapter(adapter);
}
/**
* 加载view的方法
*/
private void intiView() {
viewPager = findViewById(R.id.viewPager);
textView = findViewById(R.id.looper_title_tv);
linearLayout = findViewById(R.id.looper_point_container_lv);
}
}
下一步就是在主页面进行设置数据,首先是把我们自定义view类的实例化绑定主页面内的自定义view,当然设置数据就不和ViewPager设置数据一样了,我们需要用我们自定义view的java类里面自己写的设置数据的方法,然后把两个形参? ? “设置ViewPager的适配器”? 和? ?“获得标题的接口实例”填进去
package com.example.viewpager;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import com.example.viewpager.views.LooperPager;
public class supper_MainActivity extends AppCompatActivity {
private LooperPager looperPager;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.supper_activity_main);
intiView();
}
private void intiView() {
//绑定布局
looperPager = findViewById(R.id.Looperpager);
//设置数据
looperPager.setData(new PagerAdapter() {
@Override
public int getCount() {
return 0;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return false;
}
}, new LooperPager.BindTitleLisener() {
@Override
public String getTitle(int position) {
return null;
}
});
}
}
下一步把图片数据设置进去,这里我们先创建一个Java类用来当做容器,这个类有两个属性,string类型的标题和integer类型的地址,然后构造器和get set都写上
package com.example.viewpager.views;
public class PagerItem {
private String title;//标题
private Integer picResId; //图片地址
public PagerItem() {
}
public PagerItem(String title, Integer picResId) {
this.title = title;
this.picResId = picResId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getPicResId() {
return picResId;
}
public void setPicResId(Integer picResId) {
this.picResId = picResId;
}
}
然后在主页面声明一个泛型为这个容器的集合,接着把图片和标题填入集合。最后就是把我们的集合放进ViewPager的适配器里面和后面的获得标题的方法里面来获得各种数据,
package com.example.viewpager;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import com.example.viewpager.views.LooperPager;
import com.example.viewpager.views.PagerItem;
import java.util.ArrayList;
import java.util.List;
public class supper_MainActivity extends AppCompatActivity {
private LooperPager looperPager;
private List<PagerItem> list = new ArrayList<>();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.supper_activity_main);
intiData();//这里数据填充要写在加载组件上面,如果写在下面,需要在方法内部写上刷新数据的方法
intiView();//加载组件的方法
}
/**
* 填充数据
*/
private void intiData(){
list.add(new PagerItem("第一张图片",R.mipmap.img1));
list.add(new PagerItem("第二张图片",R.mipmap.mig2));
list.add(new PagerItem("第三张图片",R.mipmap.mig3));
list.add(new PagerItem("第四张图片",R.mipmap.mig4));
}
private void intiView() {
//绑定布局
looperPager = findViewById(R.id.Looperpager);
//设置数据
looperPager.setData(new PagerAdapter() {
@Override
public int getCount() {
return list.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
/**
* 初始化
* @param container
* @param position
* @return
*/
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
//绑定布局
View item = LayoutInflater.from(container.getContext()).inflate(R.layout.item,container,false);
//设置数据
ImageView imageView = item.findViewById(R.id.imageView);
//先把imageview绑定
int realPosition = position % list.size();
imageView.setImageResource(list.get(realPosition).getPicResId());
//然后在imageview中填入集合中的图片数据
if (imageView.getParent() instanceof ViewGroup){
((ViewGroup) imageView.getParent()).removeView(imageView);
}
//不添加这行代码会报错,改子类已经拥有一个父类,这里我们判断如果父类是group就在父类中删除,
// 如果不是就直接添加进pager里面
container.addView(imageView);
return imageView;
}
/**
* 销毁
* 作用是达到循环使用,不会导致溢出
* @param container
* @param position
* @param object
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//删除数据
container.removeView((View) object);
}
}, new LooperPager.BindTitleLisener() {
@Override
//获得当前位置图片的标题
public String getTitle(int position) {
return list.get(position).getTitle();
}
});
}
}
最终效果会随着图片的滑动上面的标题随之改变?
?这一节里我们创建了一个自定义控件的类,我们只有一个需要向外部要数据的方法,就是setData,我们向外部要两个数据,一个是一个适配器,用来给ViewPager填充数据,一个是自定义的接口用来给标题填充数据
下一节我们再对节的代码进行下一步优化
|