Gloomy's Blog

Gloomy's Blog Website

0%

Android-RecyclerView-item上下切换(带动画实现)

<Excerpt in index | 首页摘要>

Android-RecyclerView-item上下切换(带动画实现)

<The rest of contents | 余下全文>

先来看下效果图:

ss

github

已经封装:

RecyclerViewSwopItem

实现思路

首先一个RecyclerView、

然后在item的两个按钮上增加点击事件

在事件中对item和交换的item执行动画操作

难点:

难点在于如何获取要与之交换的itemview!

代码

我这里只实现了向上交换,向下交换同理可得!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package com.gloomyer.ndkdemo1;

import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {


static {
System.loadLibrary("native-lib");
}

public native String stringFromJNI();

RecyclerView mRecyclerView;

List<String> mDatas;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//布局里面就一个充满屏幕的RecyclerView
mRecyclerView = (RecyclerView) findViewById(R.id.mRecyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
MyAdapter mAdapter = new MyAdapter();
initData();
mRecyclerView.setAdapter(mAdapter);
//上下左右边距
mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.left = 20;
outRect.right = 20;
outRect.top = 30;
}
});
}
//初始化数据
private void initData() {
mDatas = new ArrayList<>();
for (int i = 0; i < 100; i++) {
mDatas.add("item pos:" + i + "|| value:" + stringFromJNI());
}
}
//view holder
private class ViewHolder extends RecyclerView.ViewHolder {
TextView pos;
TextView value;
Button top;
Button bottom;
View content;

public ViewHolder(View itemView) {
super(itemView);
content = itemView;
pos = (TextView) itemView.findViewById(R.id.pos);
value = (TextView) itemView.findViewById(R.id.text);
top = (Button) itemView.findViewById(R.id.top);
bottom = (Button) itemView.findViewById(R.id.bottom);
}
}

private class MyAdapter extends RecyclerView.Adapter<ViewHolder> {

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MainActivity.this)
.inflate(R.layout.item, parent, false);//填充item布局,很简单的布局就不贴代码了
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
//设置一下数据和按钮的显示
holder.pos.setText("pos:" + position);
holder.value.setText(mDatas.get(position));
holder.top.setVisibility(position == 0 ? View.GONE : View.VISIBLE);
holder.bottom.setVisibility(position == getItemCount() - 1 ? View.GONE : View.VISIBLE);

holder.top.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//执行向上动画
//平移
//获取两个item之间间距占一个item的百分比,间距为固定值30
final AnimationSet set
= new AnimationSet(true);
final float value = 30.0f / holder.content.getHeight();
TranslateAnimation translate
= new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, -1 - value);
translate.setFillAfter(true);
translate.setDuration(300);
set.addAnimation(translate);
set.setFillAfter(true);
set.setDuration(300);
set.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
holder.content.setAlpha(0.8f);
}

@Override
public void onAnimationEnd(Animation animation) {
holder.content.setAlpha(1.0f);
mDatas.add(position - 1, mDatas.remove(position));
notifyItemChanged(position);
notifyItemChanged(position - 1);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});


//移动上一个!
//首先获取当前完整可见的item
final LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
int firstVisibleItemPosition = layoutManager.findFirstCompletelyVisibleItemPosition();

//将要与之交换的item执行动画的操作封装成Runnable 后面会讲为什么!
Runnable run = new Runnable() {
@Override
public void run() {
//找到上一个viewholder
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
int last = position - firstVisibleItemPosition;
final View view = mRecyclerView.getChildAt(last - 1);

AnimationSet set1
= new AnimationSet(true);
TranslateAnimation translate1
= new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, 0,
TranslateAnimation.RELATIVE_TO_SELF, 1 + value);
translate1.setFillAfter(true);
translate1.setDuration(300);
set1.addAnimation(translate1);
set1.setFillAfter(true);
set1.setDuration(300);
set1.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
view.setAlpha(0.8f);
}

@Override
public void onAnimationEnd(Animation animation) {
view.setAlpha(1.0f);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});

holder.content.startAnimation(set);
view.startAnimation(set1);
}
};
//如果第一个完全可见的item是大于或者等于自身的坐标,说明上一层view没有完整
//需要滚动至要与之交换的view!
if (firstVisibleItemPosition >= position) {
//如果上下交换,作为当前上面的view不可见需要滑动到它完全可见为止
mRecyclerView.scrollToPosition(position - 1);
mRecyclerView.postDelayed(run, 100);
//这里着重说明下,因为上述的滚动是耗时操作
//如果需要执行这个那么后续操作需要延时,否则会nullpoint!
} else {
run.run();
}


}
});
}

@Override
public int getItemCount() {
return mDatas == null ? 0 : mDatas.size();
}
}
}