前面两篇文章已经把组合控件和自绘控件介绍了,咱们这一次就来看看继承控件的关键点!
继承控件就是继承已有的控件,创建新控件,保留继承的父控件的特性,并且还可以引入新特性。下面就以支持横向滑动删除列表项的自定义ListView的实现来介绍。
1、创建删除按钮布局delete_btn.xml,这个布局是在横向滑动列表项后显示的页面效果:
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff00"
android:padding="5px"
android:text="删除"
android:textColor="#f7f5f5"
android:textSize="16px"
android:textStyle="bold">
</Button>
public class CustomListView extends ListView implements View.OnTouchListener,
GestureDetector.OnGestureListener {
//手势动作探测器
private GestureDetector mGestureDetector;
// 删除事件监听器
public interface OnDeleteListener {
void onDelete(int index);
}
private OnDeleteListener mOnDeleteListener;
//删除的按钮
private View mDeleteBtn;
//列表项布局
private ViewGroup mItemLayout;
// 选择的列表项
private int mSelectedItem;
// 当前删除按钮是否显示出来了
private boolean isDeleteShown;
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
initialization();
}
//初始化操作
private void initialization() {
//创建手势监听器对象
mGestureDetector = new GestureDetector(getContext(), this);
//监听onTouch事件
setOnTouchListener(this);
}
// 设置删除监听事件
public void setOnDeleteListener(OnDeleteListener listener) {
mOnDeleteListener = listener;
}
@Override
public boolean onDown(MotionEvent e) {
if (!isDeleteShown) {
mSelectedItem = pointToPosition((int) e.getX(), (int) e.getY());
}
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// 如果当前删除按钮没有显示出来,并且x方向滑动的速度大于y方向的滑动速度
if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {
mDeleteBtn = LayoutInflater.from(getContext()).inflate(
R.layout.delete_btn, null);
mDeleteBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mItemLayout.removeView(mDeleteBtn);
mDeleteBtn = null;
isDeleteShown = false;
mOnDeleteListener.onDelete(mSelectedItem);
}
});
mItemLayout = (ViewGroup) getChildAt(mSelectedItem
- getFirstVisiblePosition());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.CENTER_VERTICAL);
mItemLayout.addView(mDeleteBtn, params);
isDeleteShown = true;
}
return false;
}
//触摸删除监听事件
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isDeleteShown) {
hideDelete();
return false;
} else {
return mGestureDetector.onTouchEvent(event);
}
}
// 隐藏删除按钮
public void hideDelete() {
mItemLayout.removeView(mDeleteBtn);
mDeleteBtn = null;
isDeleteShown = false;
}
public boolean isDeleteShown() {
return isDeleteShown;
}
}
3、定义列表项布局custom_listview_item.xml,它的结构很简单,只包含了一个TextView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/content_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="30px"
android:gravity="center_vertical|left" />
</RelativeLayout>
4、定义适配器类CustomListViewAdapter,继承自ArrayAdapter<String>:
package com.example.administrator.myapplication;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
/**
* Created by Administrator on 2017/1/4 0004.
*/
public class CustomListViewAdapter extends ArrayAdapter<String> {
public CustomListViewAdapter(Context context, int resource, List<String> objects) {
super(context, resource, objects);
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(
R.layout.custom_listview_item, null);
} else {
view = convertView;
}
TextView contentTv = (TextView) view.findViewById(R.id.content_tv);
contentTv.setText(getItem(position));
return view;
}
}
5、在activity_main.xml中引入自定义的ListView:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.administrator.myapplication.MainActivity"> <com.example.administrator.myapplication.CustomListView android:id="@+id/custom_lv" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
6、在MainActivity中对列表做初始化、设置列表项删除按钮点击事件等处理:
package com.example.administrator.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/*
Android自定义View的三种实现方式
* 1、组合控件
* 2、自绘控件
* 3、继承控件
*
*
*
* */
public class MainActivity extends AppCompatActivity {
// 自定义Lv
private CustomListView mCustomLv;
// 自定义适配器
private CustomListViewAdapter mAdapter;
// 内容列表
private List<String> contentList = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initContentList();
initview();
}
private void initContentList() {
for (int i = 0; i < 20; i++) {
contentList.add("内容项" + i);
}
}
private void initview() {
mCustomLv = (CustomListView) findViewById(R.id.custom_lv);
mCustomLv.setOnDeleteListener(new CustomListView.OnDeleteListener() {
@Override
public void onDelete(int index) {
contentList.remove(index);
mAdapter.notifyDataSetChanged();
}
});
mAdapter = new CustomListViewAdapter(MainActivity.this, 0, contentList);
mCustomLv.setAdapter(mAdapter);
}
@Override
public void onBackPressed() {
if (mCustomLv.isDeleteShown()) {
mCustomLv.hideDelete();
return;
}
super.onBackPressed();
}
}
7、运行效果如下: