xUtils获取数据+ ListView 展示 + 滑动删除数据
题目:
1, 通过xUtils 获取网络数据;
2, 将数据展示到ListView中, ListView 要求自定义
3, 每个条目显示时, 添加渐变动画, 5秒后显示列表
4, 左划每个条目, 弹出删除按钮
5, 点击删除按钮, 从数据源中删除数据
导入jar包
xUtils 和 gson 的jar包
清单文件:
添加权限 + 引入依赖
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:name=".demo01.MyApp"
页面:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.bw_test.demo04.Main2Activity"> <bw.com.bw_test.demo04.MyListView android:id="@+id/my_list_view" android:layout_width="fill_parent" android:layout_height="wrap_content"> </bw.com.bw_test.demo04.MyListView> </LinearLayout>
my_list_view_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="30dp"> <ImageView android:layout_width="150dp" android:layout_height="150dp" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="24sp" android:layout_marginTop="60dp" android:text="名称"/> </LinearLayout>
delete_button.xml
<Button xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/delete_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除" android:background="#FF0000"> </Button>
代码:
MyListView.java
public class MyListView extends ListView implements View.OnTouchListener,GestureDetector.OnGestureListener { // GestureDetector实例用于监听手势 private GestureDetector mGestureDetector; private Boolean isDeleteShown = false; private ViewGroup itemLayout; private View deleteButton; private int selecetedItem; private OnDeleteListener mOnDeleteListener; public MyListView(Context context, AttributeSet attrs) { super(context, attrs); // 创建GestureDetector实例用于监听手势 mGestureDetector = new GestureDetector(getContext(),this); // 给MyListView注册touch监听事件 setOnTouchListener(this); } public void setOnDeleteListener(OnDeleteListener onDeleteListener) { mOnDeleteListener = onDeleteListener; } //定义一个接口 public interface OnDeleteListener { void onDelete(int index); } //------>以下方法为OnGestureListener接口的实现 // 轻触触摸屏,由MotionEvent ACTION_DOWN触发 @Override public boolean onDown(MotionEvent e) { if (!isDeleteShown) { selecetedItem = pointToPosition((int)e.getX(),(int)e.getY()); } return false; } // 按住或者拖动的状态(和onDown的区别),由MotionEvent ACTION_DOWN触发 @Override public void onShowPress(MotionEvent e) { } // 触摸后松开,由MotionEvent ACTION_UP触发 @Override public boolean onSingleTapUp(MotionEvent e) { return false; } // 按下触摸屏、并拖动,由一个ACTION_DOWN、多个ACTION_MOVE触发 @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } //长按触摸屏,由多个ACION_DOWN触发 @Override public void onLongPress(MotionEvent e) { } // 按下触摸屏、快速移动后松开,由一个ACTION_DOWN、多个ACTION_MOVE、一个ACTION_UP触发 // e1: 第一个ACTION_DOWN MotionEvent 并且只有一个 // e2: 最后一个ACTION_MOVE MotionEvent // volocityX: X轴上的移动速度 // volocityY: Y轴上的移动速度 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) { deleteButton = LayoutInflater.from(getContext()).inflate(R.layout.delete_button,null); //TODO 设置删除按钮出现时的动画 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(deleteButton,"alpha",0.0f,1.0f); objectAnimator.setDuration(5000); objectAnimator.start(); // 回调MainActivty中的onDelete deleteButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { itemLayout.removeView(deleteButton); deleteButton = null; isDeleteShown = false; mOnDeleteListener.onDelete(selecetedItem); } }); // 在选择的item上添加deleteButton itemLayout = (ViewGroup) getChildAt(selecetedItem - getFirstVisiblePosition()); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); params.addRule(RelativeLayout.CENTER_VERTICAL); itemLayout.addView(deleteButton,params); isDeleteShown = true; } return false; } //------>以下方法为OnTouchListener接口的实现 // onTouch作为中转站,触发OnGestureListener的callback // 如果删除按钮已经显示,就将它移除掉。 // 如果删除按钮没有显示,使用GestureDetector来处理当前手势。 @Override public boolean onTouch(View v, MotionEvent event) { if (isDeleteShown) { itemLayout.removeView(deleteButton); deleteButton = null; isDeleteShown = false; return false; } else { return mGestureDetector.onTouchEvent(event); } } }
Main2Activity.java
private MyListView myListView;//控件 private String path = "http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1"; private List<CookBook.DataBean> data = new ArrayList<>();//数据源 private MyAdapter adapter;//适配器 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); initList(); } private void initList() { myListView = (MyListView) findViewById(R.id.my_list_view); //通过xUtils 获取数据 RequestParams params = new RequestParams(path); x.http().get(params, new Callback.CommonCallback<String>() { @Override public void onSuccess(String s) { //解析数据 CookBook cookBook = new Gson().fromJson(s,CookBook.class); data = cookBook.getData(); //设置适配器 adapter = new MyAdapter(Main2Activity.this,data); myListView.setAdapter(adapter); } @Override public void onError(Throwable throwable, boolean b) { } @Override public void onCancelled(CancelledException e) { } @Override public void onFinished() { } }); //为ListView 设置删除的事件监听器 myListView.setOnDeleteListener(new MyListView.OnDeleteListener() { @Override public void onDelete(int index) { data.remove(index); adapter.notifyDataSetChanged(); } }); } }
MyAdapter.java
public class MyAdapter extends BaseAdapter { public Context context; private List<CookBook.DataBean> data; public MyAdapter(Context context,List<CookBook.DataBean> data) { this.context = context; this.data = data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if(convertView==null) { convertView = LayoutInflater.from(context).inflate(R.layout.my_list_view_item,parent,false); //TODO 设置View进入时的动画 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(convertView,"alpha",0.0f,1.0f); objectAnimator.setDuration(5000); objectAnimator.start(); viewHolder = new ViewHolder(); viewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_id); viewHolder.tv = (TextView) convertView.findViewById(R.id.text_view); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.tv.setText(data.get(position).getTitle()); ImageOptions options = new ImageOptions.Builder() .setCircular(true) .setUseMemCache(true) .setFailureDrawableId(R.mipmap.ic_launcher) .setLoadingDrawableId(R.mipmap.ic_launcher) .build(); x.image().bind(viewHolder.iv,data.get(position).getPic(),options); return convertView; } class ViewHolder { TextView tv; ImageView iv; } }
CookBook.java-- gsonFormat 生成的实体类