就是继承已有的控件,创建新控件,保留继承的父控件的特性,并且还可以引入新特性。下面就以支持横向滑动删除列表项的自定义ListView的实现来介绍。
1、创建删除按钮布局delete_btn.xml,这个布局是在横向滑动列表项后显示的:
以上代码实现le,自定义View。重点:在重写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="#FF0000"
android:padding="5dp"
android:text="\u5220\u9664"
android:textColor="#FFFFFF"
android:textSize="16sp" >
</Button>
2、创建CustomListView类,继承自ListView,并实现了OnTouchListener和OnGestureListener接口:
package cn.com.tcl.customlistview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.RelativeLayout;
public class CustomListViewActivity extends ListView implements View.OnTouchListener, GestureDetector.OnGestureListener {
private final GestureDetector mGestureDetector;
private View mDeletBtn;
private ViewGroup mItemLAyout;
private int mSelecteditem,mlastSelecteditem;
private boolean isDelectShown;
private OnDeleteListener mOnDeleteListener;
public interface OnDeleteListener {
void onDelete(int index);
}
public CustomListViewActivity(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(getContext(), this);
setOnTouchListener(this);
}
public void setOnDeleteListener(OnDeleteListener listener) {
mOnDeleteListener = listener;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isDelectShown) {
Log.d("haha", "onTouch:---isDelectShown ");
hideDelete();
return false;
} else {
return mGestureDetector.onTouchEvent(event);
}
}
@Override
public boolean onDown(MotionEvent e) {
if(!isDelectShown){
mSelecteditem = pointToPosition((int) e.getX(),(int) e.getY());
mlastSelecteditem = mSelecteditem;
Log.d("haha", "onDown: --->mSelecteditem:"+mSelecteditem);
}
return false;
}
@Override
public void onShowPress(MotionEvent e) {
Log.d("haha", "onShowPress: ");
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d("haha", "onSingleTapUp: ");
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// Log.d("haha", "onScroll: ");
return false;
}
@Override
public void onLongPress(MotionEvent e) {
Log.d("haha", "onLongPress: ");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
mSelecteditem = pointToPosition((int) e2.getX(),(int) e2.getY());
Log.d("haha", "onFling: --->mSelecteditem:"+mSelecteditem);
if(mlastSelecteditem != mSelecteditem && isDelectShown){
hideDelete();
}
if (!isDelectShown && Math.abs(velocityX) > Math.abs(velocityY)) {
mDeletBtn = LayoutInflater.from(getContext()).inflate(R.layout.delect_btn, null);
mDeletBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mItemLAyout.removeView(mDeletBtn);
mDeletBtn = null;
isDelectShown = false;
Log.d("haha", "onClick:--> delete"+mSelecteditem);
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(mDeletBtn, params);
isDelectShown = true;
}
return false;
}
void hideDelete(){
mItemLAyout.removeView(mDeletBtn);
mDeletBtn = null;
isDelectShown = false;
}
public boolean isDelectShown() {
return isDelectShown;
}
}
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:descendantFocusability="blocksDescendants" >
<TextView
android:id="@+id/content_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="30dp"
android:gravity="center_vertical|left" />
</RelativeLayout>
</LinearLayout>
4、定义适配器类CustomListViewAdapter,继承自ArrayAdapter<String>:
public class CustomListViewAdapter extends ArrayAdapter<String> {
public CustomListViewAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
}
@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:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.test.CustomListView
android:id="@+id/custom_lv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
6、在MainActivity中对列表做初始化、设置列表项删除按钮点击事件等处理public class MainActivity extends Activity {
// 自定义Lv
private CustomListView mCustomLv;
// 自定义适配器
private CustomListViewAdapter mAdapter;
// 内容列表
private List<String> contentList = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initContentList();
mCustomLv = (CustomListView) findViewById(R.id.custom_lv);
mCustomLv.setOnDeleteListener(new OnDeleteListener() {
@Override
public void onDelete(int index) {
contentList.remove(index);
mAdapter.notifyDataSetChanged();
}
});
mAdapter = new CustomListViewAdapter(this, 0, contentList);
mCustomLv.setAdapter(mAdapter);
}
// 初始化内容列表
private void initContentList() {
for (int i = 0; i < 20; i++) {
contentList.add("内容项" + i);
}
}
@Override
public void onBackPressed() {
if (mCustomLv.isDeleteShown()) {
mCustomLv.hideDelete();
return;
}
super.onBackPressed();
}
}
以上代码实现le,自定义View。重点:在重写ListView 时,在类中进行复杂操作。比如点击事件,触摸事件,显示布局,更新布局。在此进行相关的操作~(布局的变化)然后可以写一些接口,可供使用的类调用!