android 自定义控件二之仿QQ长按删除
自定义Dialog
1.先上个效果图:
虽然效果丑了点,但主要学习修改已有的控件,例如修改Dialog控件
2.一些基本的只是进行了解
Dialog:
theme是Dialog的样式,常用样式为:
<style name="MyDialogStyle" parent="@android:Theme.Dialog"> <item name="android:windowFrame">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground"></item> <item name="android:windowIsFloating">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:backgroundDimEnabled">false</item>
</style>
3.这里在对window,view,activity的关系就个简要的说明
(1)View:最基本的UI组件,表示屏幕上的一个矩形区域。
(2)Window: 表示一个窗口,不一定有屏幕那么大,可以很大也可以很小;
它包含一个View tree和窗口的layout 参数。
View tree的root View可以通过getDecorView得到。还可以设置Window的Content View。
(3)Activity:Activity包含一个Window,该Window在Activity的attach方法中通过调用
PolicyManager.makeNewWindo创建
(4)WindowManager:一个interface,继承自ViewManager。 有一个implementation
总之,每个窗口对应着一个Window对象,一个根View和一个ViewRoot对象。要想创建一个窗口,可以调用
WindowManager的addView方法,作为参数的view将作为在该窗口上显示的根view
4.要实现上面效果代码如下:
1)自定义dialog的style,在style.xml文件添加:
1 <style name="MyDialogStyle" parent="@android:Theme.Dialog"> 2 <item name="android:windowFrame">@null</item> 3 <item name="android:windowNoTitle">true</item> 4 <item name="android:windowBackground">@android:color/white</item> 5 <item name="android:windowIsFloating">true</item> 6 <item name="android:windowContentOverlay">@null</item> 7 <item name="android:backgroundDimEnabled">false</item> 8 </style>
2)弹出框布局文件
dialogxml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="horizontal" > 6 7 <TextView 8 android:id="@+id/left" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:background="@drawable/left" 12 android:text="待办" /> 13 14 <TextView 15 android:id="@+id/right" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:background="@drawable/right" 19 android:text="删除" /> 20 21 </LinearLayout>
3)ListView和mainActivity的布局文件就不贴出来了:
ListView的item就是含有一个TextView
mainActivity就含有一个ListView;
4)自定Dialog:
1 public class MyDialog extends Dialog implements 2 android.view.View.OnClickListener { 3 4 Context context; 5 IOnClickListener iOnclicklistener; 6 private TextView left, right; 7 8 public MyDialog(Context context, int theme) { 9 super(context, theme); 10 this.context = context; 11 } 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.dialogxml); 17 left = (TextView) findViewById(R.id.left); 18 left.setOnClickListener(this); 19 right = (TextView) findViewById(R.id.right); 20 right.setOnClickListener(this); 21 } 22 23 // 直接在这里面写的话就必须要将那些参数传进来,增加这个自定义控件的负担 24 @Override 25 public void onClick(View v) { 26 iOnclicklistener = (IOnClickListener) context; 27 switch (v.getId()) { 28 case R.id.left: 29 iOnclicklistener.leftOnClick(); 30 break; 31 case R.id.right: 32 iOnclicklistener.rightOnClick(); 33 break; 34 default: 35 break; 36 } 37 38 } 39 40 public interface IOnClickListener { 41 public void leftOnClick(); 42 43 public void rightOnClick(); 44 45 } 46 47 }
上面定义了一个内部接口,这个接口可以时间动态生成作用,在继承该接口的子类中实现该接口的方法后,myDialog调用接口的方法其实就是条用继承类中所实现的方法。
5)mainActivity
1 public class MainActivity extends Activity implements IOnClickListener { 2 ListView content; 3 MyDialog myDialog; 4 private View currentView; 5 private int currentPosition; 6 List<String> listData; 7 private myAdapter myadapter; 8 9 @Override 10 protected void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.activity_main); 13 content = (ListView) findViewById(R.id.listView); 14 listData = new ArrayList<String>(); 15 16 for (int i = 0; i < 20; i++) { 17 listData.add("item" + i); 18 } 19 myadapter = new myAdapter(MainActivity.this, listData); 20 content.setAdapter(myadapter); 21 content.setOnItemLongClickListener(new ListView.OnItemLongClickListener() { 22 23 @Override 24 public boolean onItemLongClick(AdapterView<?> parent, View view, 25 int position, long id) { 26 // Toast.makeText(MainActivity.this, "你点击了 第" + position + "个", 27 // Toast.LENGTH_SHORT).show(); 28 // 设置dialog窗口展示的位置 29 myDialog = new MyDialog(MainActivity.this, 30 R.style.MyDialogStyle); 31 int[] location = new int[2]; 32 currentView = view; 33 currentPosition = position; 34 currentView.setBackgroundColor(getResources().getColor( 35 android.R.color.darker_gray)); 36 currentView.getLocationOnScreen(location);// x为0,y根据点击位置不同而不同 37 DisplayMetrics displayMetrics = new DisplayMetrics(); 38 Display display = MainActivity.this.getWindowManager() 39 .getDefaultDisplay(); 40 display.getMetrics(displayMetrics); 41 // 获取dialog的窗口 42 WindowManager.LayoutParams params = myDialog.getWindow() 43 .getAttributes(); 44 // params = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 45 46 47 params.gravity = Gravity.BOTTOM; 48 params.y = display.getHeight() - location[1]; 49 myDialog.getWindow().setAttributes(params); 50 myDialog.setCanceledOnTouchOutside(true); 51 myDialog.setOnCancelListener(new MyDialog.OnCancelListener() { 52 53 @Override 54 public void onCancel(DialogInterface dialog) { 55 currentView.setBackgroundColor(getResources().getColor( 56 android.R.color.white)); 57 } 58 }); 59 myDialog.show(); 60 61 return false; 62 } 63 64 }); 65 } 66 67 class viewHolder { 68 TextView text; 69 } 70 71 class myAdapter extends BaseAdapter { 72 private Context context; 73 74 private List<String> listData; 75 76 public myAdapter(Context context1, List<String> listData1) { 77 this.context = context1; 78 79 this.listData = listData1; 80 81 } 82 83 @Override 84 public int getCount() { 85 return listData.size(); 86 } 87 88 @Override 89 public Object getItem(int position) { 90 return listData.get(position); 91 } 92 93 @Override 94 public long getItemId(int position) { 95 return position; 96 } 97 98 @Override 99 public View getView(int position, View convertView, ViewGroup parent) { 100 viewHolder holder = null; 101 if (convertView == null) { 102 holder = new viewHolder(); 103 convertView = LayoutInflater.from(context).inflate( 104 R.layout.list_item, null); 105 holder.text = (TextView) convertView.findViewById(R.id.text); 106 convertView.setTag(holder); 107 } else { 108 holder = (viewHolder) convertView.getTag(); 109 } 110 holder.text.setText(listData.get(position)); 111 return convertView; 112 } 113 } 114 115 // 完成接口的两个方法 116 @Override 117 public void leftOnClick() { 118 myDialog.dismiss(); 119 listData.remove(listData.get(currentPosition)); 120 currentView.setBackgroundColor(getResources().getColor( 121 android.R.color.white)); 122 myadapter.notifyDataSetChanged(); 123 } 124 125 @Override 126 public void rightOnClick() { 127 // TODO Auto-generated method stub 128 myDialog.dismiss(); 129 listData.remove(listData.get(currentPosition)); 130 currentView.setBackgroundColor(getResources().getColor( 131 android.R.color.white)); 132 myadapter.notifyDataSetChanged(); 133 } 134 135 }