大家好,我是"安xiaobai",我又来和大家分享我自己写的代码了。![图片描述][1]上一次的“处女秀”我介绍的是一个安卓的图片轮播,获得大量的浏览量,所以这次我又来了。如果你没看过,或者又想了解快点这里,点这里,点这里:
http://www.imooc.com/article/9647
这次的demo是通过一个自定义ListView,来实现侧滑删除,拨号,发短信等功能。
好了上正文。一共有七个文件,四个java文件,三个布局文件。
先上效果图:![图片描述][2]![图片描述][3]
第一个文件:
public class Telphone extends Activity implements MyInterface {
private ImageView tel_back;
private SlidingItemListView mListView;
private TellDAO tellDAO;
private List mDatas;
private SlidingItemListViewAdapter adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.telphone);
initView();
}
/**
* 初始化的方法
*/
private void initView() {
tel_back = (ImageView) findViewById(R.id.tel_back);
tel_back.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(Telphone.this,MainActivity.class));
finish();
}
});
//找到ListView控件
mListView = (SlidingItemListView) findViewById(R.id.listview);
//实例化一个 查询对象
tellDAO = new TellDAO(Telphone.this);
//查询所有数据
mDatas = tellDAO.getAllTel();
//将数据传递给 adapter
adapter = new SlidingItemListViewAdapter(Telphone.this, mDatas,
mListView.getRightViewWidth());
//将adapater 配置给 ListView
mListView.setAdapter(adapter);
//实现接口 对两个按钮进行监听
adapter.SetMyInterface(this);
//实现每一项的监听事件
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
}
/**
* 实现接口 发送消息
*/
public void Onclick_ll_sendMesg_ll_right(View view, int position) {
Map map = (Map)mDatas.get(position);
Uri smsToUri = Uri.parse("smsto:"+map.get("number"));
Intent mIntent = new Intent( android.content.Intent.ACTION_SENDTO, smsToUri );
// mIntent.putExtra("sms_body", "sss"); 这个是预定短信内容
startActivity( mIntent );
}
/**
* 实现接口 拨打电话
*/
public void Onclick_ll_tellCall_ll_right(View view, int position) {
Map map = (Map)mDatas.get(position);
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:"+map.get("number")));
startActivity(intent);
}
}
这里面有两个方法是实现自定义接口的,通过这两个方法来调用系统的拨号界面,和短信界面。其他的在代码里面有详细的解释。
第二个文件:
public class TellDAO extends Activity{
private Context context;
public TellDAO(Context context){
this.context = context;
}
public List getAllTel(){
List tell = new ArrayList();
try {
Cursor cursor = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null, null);
if (cursor ==null) {
System.out.println("这里为空");
return null;
}
while (cursor.moveToNext()) {
Map<String, Object> map = new HashMap<String,Object>();
map.put("num", cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.CONTACT_ID)));
map.put("name",cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
map.put("number", cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER)));
tell.add(map);
}
} catch (Exception e) {e.printStackTrace();}
return tell;
}
}
这是查询系统中通讯录的电话号码。将查询出来的数据保存到map里面在讲map返回给调用者。
第三个文件:
public class SlidingItemListView extends ListView {
private View mPreItemView;
private View mCurrentItemView;
//用户第一点击下去的 X Y的值
private float mFirstX;
private float mFirstY;
private int mRightViewWidth;
private boolean mIsShown;
private Boolean mIsHorizontal;
/**
* 在构造方法里获取自定义的宽度(右边局部隐藏的宽度)
* @param context 上下文
* @param attrs
*/
public SlidingItemListView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.slidingitemlistview);
mRightViewWidth = (int) typedArray.getDimension(
R.styleable.slidingitemlistview_right_width, 200);
typedArray.recycle();
}
/**
* 重写onInterceptTouchEvent()
* ACTION_DOWN里获取 mCurrentItemView,mPreItemView,mFirstX,mFirstY
*/
public boolean onInterceptTouchEvent(MotionEvent ev) {
float lastX = ev.getX();
float lastY = ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mIsHorizontal = null;
mFirstX = lastX;
mFirstY = lastY;
int position = pointToPosition((int) mFirstX, (int) mFirstY);
if (position >= 0) {
View view = getChildAt(position - getFirstVisiblePosition());
mPreItemView = mCurrentItemView;
mCurrentItemView = view;
}
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
//点击隐藏布局会执行MotionEvent.ACTION_UP
if (mIsShown) {
hideRightView(mCurrentItemView);
}
break;
}
return super.onInterceptTouchEvent(ev);
}
/**
*重写onTouchEvent()方法
*/
public boolean onTouchEvent(MotionEvent ev) {
float lastX = ev.getX();
float lastY = ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
float dx = lastX - mFirstX;
float dy = lastY - mFirstY;
if (mIsHorizontal == null) {
if (!judgeScrollDirection(dx, dy)) {
// 没判断出方向 ,没有滑动的话就直接退出
break;
}
}
//如果滑动了
if (mIsHorizontal) {
if (mIsShown && mPreItemView != mCurrentItemView) {
//正在展示,前视图不等于后视图
//则隐藏前视图
hideRightView(mPreItemView);
}
// 在mPreItemView!= mCurrentItemView执行 显示隐藏的宽度
if (dx < 0 && dx > - mRightViewWidth) {
mCurrentItemView.scrollTo((int) (-dx), 0);
}
} else {
if (mIsShown) {
//竖直方向滚动 则隐藏前视图
hideRightView(mPreItemView);
}
}
break;
case MotionEvent.ACTION_UP:
if (mIsShown) {
//点击时如果有在显示的View则隐藏前视图
hideRightView(mPreItemView);
}
if (mIsHorizontal != null && mIsHorizontal) {
if (mFirstX - lastX > mRightViewWidth / 2) {
showRight(mCurrentItemView);
} else {
// 不到一半则隐藏
hideRightView(mCurrentItemView);
}
return true;
}
break;
}
return super.onTouchEvent(ev);
}
/**
* 展示隐藏的布局
* @param mCurrentItemView2
*/
private void showRight(View mCurrentItemView2) {
mCurrentItemView2.scrollTo(mRightViewWidth, 0);
mIsShown = true;
}
/**
* 隐藏布局
*/
private void hideRightView(View mCurrentItemView2) {
mCurrentItemView2.scrollTo(0, 0);
mIsShown = false;
}
/**
* @param 水平距离差
* @param 竖直距离差
* @return 水平滑动或者竖直滑动都返回true 没有判断出滑动方向则返回false
*/
private boolean judgeScrollDirection(float dx, float dy) {
if (Math.abs(dx) > 30 && Math.abs(dx) > Math.abs(dy) * 2) {
mIsHorizontal = true;
return true;
}
if (Math.abs(dy) > 30 && Math.abs(dy) > Math.abs(dx) * 2) {
mIsHorizontal = false;
return true;
}
return false;
}
/**
* 后面实例化adapter的时候要用
* 获得右边 的宽度
* @return
*/
public int getRightViewWidth() {
return mRightViewWidth;
}
/**
* 设置 右边的宽度
* @param mRightViewWidth
*/
public void setRightViewWidth(int mRightViewWidth) {
this.mRightViewWidth = mRightViewWidth;
}
}
这个文件是自定义ListView文件,是实现滑动效果的关键。
第四文件:
public class SlidingItemListViewAdapter extends BaseAdapter {
//上下文
private Context mContext;
//布局文件
private LayoutInflater mInflater;
//ListView列表
private List list;
//右边的宽度
private int mRightViewWidth;
/**
* 构造方法 初始化一些数据
* @param mContext 上下文
* @param list 列表
* @param mRightViewWidth 右边的宽度
*/
public SlidingItemListViewAdapter(Context mContext,
List list, int mRightViewWidth) {
super();
this.mContext = mContext;
this.list = list;
this.mRightViewWidth = mRightViewWidth;
mInflater = LayoutInflater.from(mContext);
}
//获得数据条目
public int getCount() {
return list.size();
}
//获得List中的每一个Item
public Object getItem(int position) {
return list.get(position);
}
//获得itemId
public long getItemId(int position) {
return position;
}
/**
* 获得view控件
*/
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
onClick listener;
if (convertView == null) {
//将ListView中每一个Item的布局文件加载进来
convertView = mInflater.inflate(R.layout.item_sliding_listview,null);
//实例化
viewHolder = new ViewHolder();
listener = new onClick();
viewHolder.Re_left = (RelativeLayout) convertView.findViewById(R.id.Re_left);
viewHolder.ll_right = (LinearLayout) convertView.findViewById(R.id.ll_right);
//找到 ListView中每一个Iten布局文件中的每一个控件
viewHolder.num = (TextView) convertView.findViewById(R.id.tv_num_Re_left);
viewHolder.name = (TextView) convertView.findViewById(R.id.tv_name_Re_left);
viewHolder.number = (TextView) convertView.findViewById(R.id.tv_path_Re_left);
viewHolder.tell = (ImageView) convertView.findViewById(R.id.img_tell_Re_left);
//找到 删除按钮 和 发送短信按钮
viewHolder.ll_delete = (LinearLayout) convertView.findViewById(R.id.ll_delete_ll_right);
viewHolder.ll_sendMessgae = (LinearLayout) convertView.findViewById(R.id.ll_sendMessge_ll_right);
//给三个个按钮设置监听事件
viewHolder.ll_delete.setOnClickListener(listener);
viewHolder.ll_sendMessgae.setOnClickListener(listener);
viewHolder.tell.setOnClickListener(listener);
//设置tag标记
convertView.setTag(viewHolder.tell.getId(),listener);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
// 获取实例
listener = (onClick) convertView.getTag(viewHolder.tell.getId());
}
// 传递position
listener.setPosition(position);
// 设置布局参数
LayoutParams lp_left = new LayoutParams(
android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
android.widget.LinearLayout.LayoutParams.MATCH_PARENT);
//将布局参数 设置给控件
viewHolder.Re_left.setLayoutParams(lp_left);
// 设置布局参数
LayoutParams lp_right = new LayoutParams(mRightViewWidth,
android.widget.LinearLayout.LayoutParams.MATCH_PARENT);
//将布局参数 设置给控件
viewHolder.ll_right.setLayoutParams(lp_right);
Map map = (Map)list.get(position);
viewHolder.num.setText(map.get("num").toString());
viewHolder.name.setText(map.get("name").toString());
viewHolder.number.setText(map.get("number").toString());
return convertView;
}
/**
* 内部类 复用监听事件
* @author First.One
*/
class onClick implements OnClickListener {
int position;
public void setPosition(int position) {
this.position = position;
}
//重写的方法
public void onClick(View v) {
switch (v.getId()) {
case R.id.img_tell_Re_left:
if (myInterface != null) {
myInterface.Onclick_ll_tellCall_ll_right(v,position);
}else {
Toast.makeText(mContext, "程序异常,请稍后再试。",2000).show();
}
break;
//删除
case R.id.ll_delete_ll_right:
list.remove(position);
SlidingItemListViewAdapter.this.notifyDataSetChanged();
break;
case R.id.ll_sendMessge_ll_right:
if (myInterface != null) {
myInterface.Onclick_ll_sendMesg_ll_right(v,position);
}else {
Toast.makeText(mContext, "这里是发送短信",
Toast.LENGTH_SHORT).show();
}
break;
}
}
}
MyInterface myInterface;
/**
* 自己定义置顶的MySetTopInterface接口
* @author First.One
* 传递两个参数,一个是被点击的View,另一个是position。
*/
public interface MyInterface {
void Onclick_ll_sendMesg_ll_right(View view,int position);
void Onclick_ll_tellCall_ll_right(View view,int position);
}
public void SetMyInterface(MyInterface myInterface) {
this.myInterface = myInterface;
}
/**
* 内部类 复用item控件里面的view控件
* @author First.One
*/
static class ViewHolder {
//左边的布局文件控件
RelativeLayout Re_left;
//右边滑动的控件
LinearLayout ll_right;
//删除按钮 发送短信 按钮
LinearLayout ll_delete;
LinearLayout ll_sendMessgae;
//编号、姓名、电话
TextView num;
TextView name;
TextView number;
//拨打电话 的图标
ImageView tell;
}
}
这个文件是自定义Adapter里面重点的是那两个内部类,实现了监听事件和View控件的重复使用。
第五个文件:
<com.example.ashixi.SlidingItemListView
xmlns:dyk="http://schemas.android.com/apk/res/com.example.ashixi"
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
android:cacheColorHint="#00000000"
android:divider="#dddbdb"
android:dividerHeight="1dp"
android:layout_below="@id/include_id"
dyk:right_width="120dp" />
这就是一个简单的布局文件,相信你能看懂。
第六个文件:
```。
<resources>
<declare-styleable name="slidingitemlistview">
<attr name="right_width" format="dimension"></attr>
</declare-styleable>
</resources>
这个文件是控制右便滑动的宽度。在自定义ListView中的构造方法会调用它。
最后一个文件 :
<!-- 左边的布局文件 -->
<RelativeLayout
android:id="@+id/Re_left"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_num_Re_left"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center"
android:textColor="#fff"
android:textSize="13sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/tv_num_Re_left" >
<TextView
android:id="@+id/tv_name_Re_left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:textSize="19sp"
android:textColor="#fff"/>
<TextView
android:id="@+id/tv_path_Re_left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_name_Re_left"
android:textColor="#fff"
android:textSize="15sp" />
</RelativeLayout>
<!-- 每一个Item后面的那个图标 -->
<ImageView
android:id="@+id/img_tell_Re_left"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:scaleType="fitXY"
android:src="@drawable/tel" />
</RelativeLayout>
<!-- 右滑的图标 -->
<LinearLayout
android:id="@+id/ll_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
<!-- 右划删除功能 -->
<LinearLayout
android:id="@+id/ll_delete_ll_right"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#F77D48"
android:gravity="center"
android:orientation="vertical"
android:padding="5dp" >
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:scaleType="fitXY"
android:src="@drawable/del_icon_normal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除"
android:textColor="#fff"
android:textSize="16sp" />
</LinearLayout>
<!-- 右滑 发送短信 -->
<LinearLayout
android:id="@+id/ll_sendMessge_ll_right"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FED33F"
android:gravity="center"
android:orientation="vertical"
android:padding="5dp" >
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:scaleType="fitXY"
android:src="@drawable/msg" />
<TextView
android:id="@+id/tv_sendMes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="短信"
android:textColor="#fff"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
这个是LiseView控件中每一个Item的布局文件,也不难。
![图片描述][4]
终于写完了.................心好累。如果你真心想学习这个demo的同学,”俺“保证我这个栗子绝对是最详细的了,没有之一...........好吧!!!!我还是要谦虚点。
![图片描述][5]
注意:
上面的文件我全部没有引入包,,所以要复制的同学小心哦!!!
上面的文件我全部没有引入包,,所以要复制的同学小心哦!!!
上面的文件我全部没有引入包,,所以要复制的同学小心哦!!!
![图片描述][6]
各位同学,"安xiaobai"我写一个文章也不容易,代码敲了半天,然后又敲了半天的字,如果你觉得文章还可以的话,就点一个推荐呗,,谢谢了。
严重申明:本文的图片全部来源于网络,如有侵权,请及时联系本人删除。
[1]: http://img.mukewang.com/57751692000109b603160194.jpg
[2]: http://img.mukewang.com/5775246b00017bb910801920.jpg
[3]: http://img.mukewang.com/5775247c0001fde310801920.jpg
[4]: http://img.mukewang.com/57751d720001108e02880240.gif
[5]: http://img.mukewang.com/57751dfc00011cc402110240.jpg
[6]: http://img.mukewang.com/57751ee70001e66003830240.gif
热门评论
楼主,我按照你这个做完后,滑动不会完全展示两个按钮,是怎么回事啊?