前言: 就是为了实现如下图的这种效果,滑动到最后一张图片时,跳转到该酒店的相册。
实现方式就是使用 RecycleView 加上 PagerSnapHelper。
PagerSnapHelper 的作用就是让 RecycleView 每次只能滑动一个 Item。
Adapter 的最后一个加上如上图红框框出来的 View ,即下面的 STLview
。在 STLView 里面会有个简单的动画效果。
STLView 代码如下:
public class STLView extends FrameLayout {
private ImageView mImgArrow;
private TextView mTxtHint;
private boolean mIsPullStatus = true;
public STLView(Context context) {
this(context, null);
}
public STLView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public STLView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
LayoutInflater.from(context).inflate(R.layout.hotel_view_stl, this, true);
mImgArrow = findViewById(R.id.img_arrow);
mTxtHint = findViewById(R.id.txt_hint);
bindHint();
}
public void setPullStatus(boolean isPullStatus) {
if(mIsPullStatus == isPullStatus) {
return;
}
mIsPullStatus = isPullStatus;
bindHint();
animArrow();
}
private void bindHint() {
if(mIsPullStatus) {
mTxtHint.setText("查看更多");
} else {
mTxtHint.setText("释放进相册");
}
}
private void animArrow() {
if(mIsPullStatus) {
ObjectAnimator.ofFloat(mImgArrow, "rotation", 180f, 00f)
.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime))
.start();
} else {
ObjectAnimator.ofFloat(mImgArrow, "rotation", 0f, 180f)
.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime))
.start();
}
}
}
里面的代码很简单,就是简单的箭头旋转的动效。看看下面的 adapter ,如下:
public class TestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_TEXT = 0;
private static final int TYPE_STL = TYPE_TEXT + 1;
private List<String> dataList;
public TestAdapter() {
dataList = new ArrayList<>();
}
public void setDataList(List<String> dataList) {
this.dataList.clear();
this.dataList.addAll(dataList);
notifyDataSetChanged();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == TYPE_TEXT) {
return new TestHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.test_holder_item_view, parent, false));
} else {
STLView stlView = new STLView(parent.getContext());
stlView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
return new STLHolder(stlView);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof TestHolder) {
((TestHolder) holder).bindView(position);
}
}
@Override
public int getItemViewType(int position) {
if (position < dataList.size()) {
return TYPE_TEXT;
} else {
return TYPE_STL;
}
}
@Override
public int getItemCount() {
int cnt = hasData() ? 1 : 0;
cnt += dataList.size();
return cnt;
}
private boolean hasData() {
return dataList.size() > 0;
}
class TestHolder extends RecyclerView.ViewHolder {
private TextView tv ;
public TestHolder(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.test_tv);
}
public void bindView(int position) {
tv.setText(dataList.get(position));
}
}
class STLHolder extends RecyclerView.ViewHolder {
public STLHolder(@NonNull View itemView) {
super(itemView);
}
}
}
代码也很简单,就是在后面添加一个 STLView 。
下面是调用的地方了。如下:
public class TestPagerSnapHelperActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private TestAdapter testAdapter;
private STLView mSTLView;
private boolean mOpenAll;
public static void enter(Context context) {
Intent intent = new Intent(context, TestPagerSnapHelperActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager_snaphelper_layout);
recyclerView = findViewById(R.id.recycle_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false));
testAdapter = new TestAdapter();
recyclerView.setAdapter(testAdapter);
SnapHelper pagerSnapHelper = new PagerSnapHelper();
pagerSnapHelper.attachToRecyclerView(recyclerView);
List<String> dataList = new ArrayList<>(5);
dataList.add("安徽");
dataList.add("浙江");
dataList.add("上海");
dataList.add("北京");
dataList.add("江苏");
testAdapter.setDataList(dataList);
recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(@NonNull View view) {
if (view instanceof STLView) {
mSTLView = (STLView) view;
}
}
@Override
public void onChildViewDetachedFromWindow(@NonNull View view) {
if (view instanceof STLView) {
mSTLView = null;
}
}
});
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (mOpenAll && newState == RecyclerView.SCROLL_STATE_IDLE) {
// 这里面实现跳转逻辑
Log.e("pagerHelper", "open");
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
mOpenAll = !canScrollMore();
Log.e("pagerHelper", "mOpenAll = " + mOpenAll);
if (mSTLView != null) {
mSTLView.setPullStatus(!mOpenAll);
}
}
});
}
private boolean canScrollMore() {
// 正数表示向左的滑动检测,负数表示向右的滑动检测
return recyclerView.canScrollHorizontally(10);
}
}
就是利用 PagerSnapHelper
实现 RecycleView
每次只滑动一项。然后监听滑动事件,是否不能继续滑动且停止滑动的时候就可以实现跳转逻辑了。