先来个效果图
由于项目需要,所以自己摸索实现了这个效果。主要是通过自定义HorizontalScrollView实现,然后将HorizontalScrollView嵌入单个item布局中去。
代码很简单,我就不废话了,下面上代码。
自定义HorizontalScrollView
public class SlidingButtonView extends HorizontalScrollView {
private LinearLayout linearLayout;
private int mScrollWidth;
private IonSlidingButtonListener mIonSlidingButtonListener;
private Boolean isOpen = false;
private Boolean once = false;
public SlidingButtonView(Context context) {
this(context, null);
}
public SlidingButtonView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public SlidingButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//去掉渐变色
this.setOverScrollMode(OVER_SCROLL_NEVER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(!once){
linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
once = true;
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if(changed){
this.scrollTo(0,0);
mScrollWidth = linearLayout.getWidth();
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
mIonSlidingButtonListener.onDownOrMove(this);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
changeScrollx();
return true;
default:
break;
}
return super.onTouchEvent(ev);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
public void changeScrollx(){
if(getScrollX() >= (mScrollWidth/2)){
this.smoothScrollTo(mScrollWidth, 0);
isOpen = true;
mIonSlidingButtonListener.onMenuIsOpen(this);
}else{
this.smoothScrollTo(0, 0);
isOpen = false;
}
}
public void openMenu()
{
if (isOpen){
return;
}
this.smoothScrollTo(mScrollWidth, 0);
isOpen = true;
mIonSlidingButtonListener.onMenuIsOpen(this);
}
public void closeMenu() {
if (!isOpen){
return;
}
this.smoothScrollTo(0, 0);
isOpen = false;
}
public void setSlidingButtonListener(IonSlidingButtonListener listener){
mIonSlidingButtonListener = listener;
}
public interface IonSlidingButtonListener{
void onMenuIsOpen(View view);
void onDownOrMove(SlidingButtonView slidingButtonView);
}
}
RecyclerView的适配器
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> implements SlidingButtonView.IonSlidingButtonListener {
private Context mContext;
private IonSlidingViewClickListener mIDeleteBtnClickListener;
private List<String> mDatas = new ArrayList<String>();
private SlidingButtonView mMenu = null;
public Adapter(Context context, IonSlidingViewClickListener listener) {
mContext = context;
mIDeleteBtnClickListener = listener;
for (int i = 0; i < 10; i++) {
mDatas.add("");
}
}
@Override
public int getItemCount() {
return mDatas.size();
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.layout_content.getLayoutParams().width = Utils.getScreenWidth(mContext);
holder.layout_content.setOnClickListener(v -> {
if (menuIsOpen()) {
closeMenu();
} else {
int n = holder.getLayoutPosition();
mIDeleteBtnClickListener.onItemClick(v, n);
}
});
holder.btn_Delete.setOnClickListener(v -> {
int n = holder.getLayoutPosition();
mIDeleteBtnClickListener.onDeleteBtnCilck(v, n);
});
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_layout_item, new RelativeLayout(mContext), false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView btn_Delete;
public ViewGroup layout_content;
// public LinearLayout mLinearLayoutView;
public MyViewHolder(View itemView) {
super(itemView);
// mLinearLayoutView = (LinearLayout) itemView.findViewById(R.id.linear_layout_view);
btn_Delete = (TextView) itemView.findViewById(R.id.tv_delete);
layout_content = (ViewGroup) itemView.findViewById(R.id.button);
((SlidingButtonView) itemView).setSlidingButtonListener(Adapter.this);
}
}
public void addData(int position) {
mDatas.add(position, "1234");
notifyItemInserted(position);
}
public void removeData(int position){
mDatas.remove(position);
notifyItemRemoved(position);
}
@Override
public void onMenuIsOpen(View view) {
mMenu = (SlidingButtonView) view;
}
@Override
public void onDownOrMove(SlidingButtonView slidingButtonView) {
if(menuIsOpen()){
if(mMenu != slidingButtonView){
closeMenu();
}
}
}
public void closeMenu() {
mMenu.closeMenu();
mMenu = null;
}
public Boolean menuIsOpen() {
if(mMenu != null){
return true;
}
return false;
}
public interface IonSlidingViewClickListener {
void onItemClick(View view, int position);
void onDeleteBtnCilck(View view, int position);
}
}
item布局
<?xml version="1.0" encoding="utf-8"?>
<com.example.asus.four.customUI.recycler.SlidingButtonView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginBottom="1dp"
android:background="@android:color/white">
<RelativeLayout
android:id="@+id/relative"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:id="@+id/linear_layout"
android:layout_toRightOf="@+id/layout_content">
<TextView
android:id="@+id/tv_delete"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background="#a90202"
android:gravity="center"
android:text="删除"
android:textColor="#ffffff"
android:textSize="16sp"
android:typeface="serif" />
<TextView
android:layout_width="80dp"
android:layout_height="match_parent"
android:text="分享"
android:background="#0c7478"
android:textColor="#ffffff"
android:gravity="center"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/layout_content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/button"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="#ffffff"
android:text="测试"
android:textColor="#DD000000"
android:textSize="50dp" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</com.example.asus.four.customUI.recycler.SlidingButtonView>
我的项目需要,所以我使用的是Fragment,当然可以替换为Activity。
public class InfoBallFragment extends Fragment implements Adapter.IonSlidingViewClickListener{
private RecyclerView mRecyclerView;
private Adapter mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.recycler_activity_main, container, false);
initView(view);
setAdapter();
return view;
}
private void initView(View view){
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
}
private void setAdapter(){
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.setAdapter(mAdapter = new Adapter(getContext(), this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
@Override
public void onItemClick(View view, int position) {
}
@Override
public void onDeleteBtnCilck(View view, int position) {
mAdapter.removeData(position);
}
}
笔者能力有限,不足之处欢迎指出!