我有一个ListView,子view是HorizontalScrollView,当我对的ListView中的第一个子HorizontalScrollView从右边滑动到左边,把删除按钮显示出来之后,我再操作ListView上下滚动时,ListView会复用之前滑动HorizontalScrollView的view.
我的代码:
ListView 子view布局:
<?xml version="1.0" encoding="utf-8"?>
<com.example.administrator.myapplication.DeleteView
android:id="@+id/GrafDelete_root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f1f1f1"
android:scrollbars="none"
>
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="920px"
android:layout_height="180px"
android:orientation="horizontal">
<RelativeLayout
android:id="@+id/re_select"
android:layout_width="80px"
android:layout_height="180px"
android:background="@color/colorAccent">
<ImageView
android:id="@+id/select"
android:layout_width="36px"
android:layout_height="36px"
android:layout_centerInParent="true"
android:scaleType="centerCrop"/>
</RelativeLayout>
<AbsoluteLayout
android:id="@+id/ab_view_bg"
android:layout_width="720px"
android:layout_height="180px">
<TextView
android:id="@+id/text_title"
android:layout_width="450px"
android:layout_height="80px"
android:layout_x="20px"
android:layout_y="30px"
android:gravity="center_vertical"
android:maxLines="2"
android:textColor="#515151"
android:textSize="30px"
/>
</AbsoluteLayout>
<AbsoluteLayout
android:id="@+id/ab_delete_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<View
android:id="@+id/view_delete_bg"
android:layout_width="120px"
android:layout_height="180px"
android:background="#ff0000"
></View>
<TextView
android:id="@+id/text_delete"
android:layout_width="120px"
android:layout_height="60px"
android:layout_y="90px"
android:gravity="center"
android:text="删除"
android:textColor="#ffffff"
android:textSize="30px"
/>
</AbsoluteLayout>
</LinearLayout>
</com.example.administrator.myapplication.DeleteView>
自定义的HorizontalScrollView,可以从又滑动到左边,显示被影藏的删除按钮:
public class DeleteView extends HorizontalScrollView {
private static final int SWIPE_MIN_DISTANCE = 5;
private static final int SWIPE_THRESHOLD_VELOCITY = 600;
private GestureDetector gestureDetector;
private Context context;
private int start;//开始滑动的位置
private int end;//结束滑动的位置
private VelocityTracker velocityTracker;
private int width;//屏幕宽度的额外宽度。
private boolean isEnableScroll;//是否打开水平滑动 true可以水平滑动 false不能水平滑动
public DeleteView(Context context) {
super(context);
}
public DeleteView(Context context, AttributeSet attrs) {
super(context, attrs);
width = 120;//设定额外的宽度
gestureDetector = new GestureDetector(new MyGestureDetector());
}
public DeleteView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
}
if (!isEnableScroll)
return true;
if (gestureDetector.onTouchEvent(event))
return true;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
start = (int) event.getRawX();
}
if (event.getAction() == MotionEvent.ACTION_UP) {
end = (int) event.getRawX();
if (start > end) {
if (getScrollX() < width / 2 || velocityTracker.getXVelocity() > SWIPE_THRESHOLD_VELOCITY) {
smoothScrollTo(0, 0);
} else {
smoothScrollTo(width, 0);
}
}
if (start < end) {
if (getScrollX() > width / 2 || velocityTracker.getXVelocity() > SWIPE_THRESHOLD_VELOCITY) {
smoothScrollTo(width, 0);
} else {
smoothScrollTo(0, 0);
}
}
velocityTracker.clear();
return true;
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
velocityTracker.addMovement(event);
}
return super.onTouchEvent(event);
}
class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (!isEnableScroll)
return true;
try {
//right to left
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
smoothScrollTo(width, 0);
return true;
}
} catch (Exception e) {
// nothing
}
return false;
}
}
//是否开启水平滑动
public void setEnAbleHorizontalScroll(boolean b) {
if (b == isEnableScroll) {
return;
} else {
isEnableScroll = b;
}
if (!isEnableScroll) {
smoothScrollTo(0, 0);
}
}
}
Adapter:
public class ListAdapter extends BaseAdapter {
private Context context;
private ArrayList<ListItem> items;
private boolean isAble;
public ListAdapter(Context context, ArrayList<ListItem> items) {
this.context = context;
this.items = items;
}
@Override
public int getCount() {
return items.size();
}
@Override
public ListItem getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder.mDelete_Item_root = (DeleteView) convertView.findViewById(R.id.GrafDelete_root);
holder.ll_content = (LinearLayout) convertView.findViewById(R.id.ll_content);
holder.re_select = (RelativeLayout) convertView.findViewById(R.id.re_select);
holder.select = (ImageView) convertView.findViewById(R.id.select);
holder.ab_view_bg = (AbsoluteLayout) convertView.findViewById(R.id.ab_view_bg);
holder.text_title = (TextView) convertView.findViewById(R.id.text_title);
AbsoluteLayout ab_delete_bg = (AbsoluteLayout) convertView.findViewById(R.id.ab_delete_bg);
holder.view_delete_bg = convertView.findViewById(R.id.view_delete_bg);
TextView text_delete = (TextView) convertView.findViewById(R.id.text_delete);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (isAble) {//Open edit
DeleteView.LayoutParams layoutParams = new DeleteView.LayoutParams(920, 180);
layoutParams.leftMargin = 0;
holder.ll_content.setLayoutParams(layoutParams);
((DeleteView) convertView).setEnAbleHorizontalScroll(false);
} else {//Editing is not open
DeleteView.LayoutParams layoutParams = new DeleteView.LayoutParams(920, 180);
layoutParams.leftMargin = -80;
holder.ll_content.setLayoutParams(layoutParams);
((DeleteView) convertView).setEnAbleHorizontalScroll(true);
}
if (items.get(position).isSelected) {
holder.select.setBackgroundResource(R.mipmap.item_selected1);
} else {
holder.select.setBackgroundResource(R.mipmap.item_select_un);
}
View.OnTouchListener listener = new View.OnTouchListener() {
boolean select_out, delete_out;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
switch (v.getId()) {
case R.id.re_select:
select_out = false;
break;
case R.id.view_delete_bg:
holder.view_delete_bg.setAlpha(0.5f);
delete_out = false;
break;
}
break;
case MotionEvent.ACTION_MOVE:
switch (v.getId()) {
case R.id.re_select:
int x = (int) event.getX();
int y = (int) event.getY();
if (x < 0 || y < 0 || x > holder.re_select.getWidth() || y > holder.re_select.getHeight()) {
select_out = true;
}
break;
case R.id.view_delete_bg:
int x2 = (int) event.getX();
int y2 = (int) event.getY();
if (x2 < 0 || y2 < 0 || x2 > holder.view_delete_bg.getWidth() || y2 > holder.view_delete_bg.getHeight()) {
holder.view_delete_bg.setAlpha(1.0f);
delete_out = true;
}
break;
}
break;
case MotionEvent.ACTION_UP:
switch (v.getId()) {
case R.id.re_select:
if (select_out) {
return true;
}
if (items.get(position).isSelected) {
items.get(position).isSelected = false;
holder.select.setBackgroundResource(R.mipmap.item_select_un);
} else {
items.get(position).isSelected = true;
holder.select.setBackgroundResource(R.mipmap.item_selected1);
}
break;
case R.id.view_delete_bg:
holder.view_delete_bg.setAlpha(1.0f);
if (delete_out)
return true;
if (isAble)
return true;
break;
}
break;
case MotionEvent.ACTION_CANCEL:
switch (v.getId()) {
case R.id.re_select:
break;
case R.id.view_delete_bg:
holder.view_delete_bg.setAlpha(1.0f);
break;
}
break;
}
return true;
}
};
holder.re_select.setOnTouchListener(listener);
holder.view_delete_bg.setOnTouchListener(listener);
holder.text_title.setText(items.get(position).mString);
return convertView;
}
private class ViewHolder {
TextView text_title;
RelativeLayout re_select;
ImageView select;
AbsoluteLayout ab_view_bg, ab_delete_bg;
View view_delete_bg;
// TextView text_delete;
LinearLayout ll_content;
DeleteView mDelete_Item_root;
}
/**
* You can edit
*/
public void setIsAble(boolean b) {
if (b == isAble) {
return;
} else {
isAble = b;
notifyDataSetChanged();
}
}
}
Activity:
public class MainActivity extends AppCompatActivity {
private ListView listView;
private TextView tv_button;
private ArrayList<ListItem> mArrayList = new ArrayList<>();
private boolean isAble;
private ListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
tv_button = (TextView) findViewById(R.id.tv_button);
getListItem();
adapter = new ListAdapter(this, mArrayList);
listView.setAdapter(adapter);
setListener();
}
public void setListener() {
View.OnTouchListener listener = new View.OnTouchListener() {
boolean delete_out;
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN:
switch (arg0.getId()) {
case R.id.tv_button:
tv_button.setAlpha(0.5f);
delete_out = false;
break;
}
break;
case MotionEvent.ACTION_MOVE:
switch (arg0.getId()) {
case R.id.tv_button:
int x2 = (int) arg1.getX();
int y2 = (int) arg1.getY();
if (x2 < 0 || y2 < 0 || x2 > tv_button.getWidth() || y2 > tv_button.getHeight()) {
tv_button.setAlpha(1.0f);
delete_out = true;
}
break;
}
break;
case MotionEvent.ACTION_UP:
switch (arg0.getId()) {
case R.id.tv_button:
tv_button.setAlpha(1.0f);
if (delete_out)
return true;
changeState();
break;
}
break;
case MotionEvent.ACTION_CANCEL:
switch (arg0.getId()) {
case R.id.tv_button:
tv_button.setAlpha(1.0f);
break;
}
}
return true;
}
};
tv_button.setOnTouchListener(listener);
}
//点编辑或完成时切换状态
private void changeState() {
if (isAble) {
isAble = false;
tv_button.setText("编辑");
} else {
isAble = true;
tv_button.setText("完成");
}
adapter.setIsAble(isAble);
}
private void getListItem() {
for (int i = 0; i < 20; i++) {
ListItem listItem = new ListItem();
listItem.mString = i + "\t" + "ScrollView and HorizontalScrollView conflict";
mArrayList.add(listItem);
}
}
}