今天我用自己写的一个Demo 和大家详细介绍一个Android中的对话框的使用技巧。
1.确定取消对话框
对话框中有2个按钮 通过调用 setPositiveButton 方法 和 setNegativeButton 方法 可以设置按钮的显示内容以及按钮的监听事件。
我们使用AlerDialog 创建对话框
AlertDialog.Builder builder = new AlertDialog.Builder(MainDialog.this);
使用builder设置对话框的title button icon 等等
builder.setIcon(R.drawable.icon); builder.setTitle("你确定要离开吗?"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //这里添加点击确定后的逻辑 showDialog("你选择了确定"); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //这里添加点击确定后的逻辑 showDialog("你选择了取消"); } }); builder.create().show();
这个dialog用于现实onClick后监听的内容信息
private void showDialog(String str) { new AlertDialog.Builder(MainDialog.this) .setMessage(str) .show(); }
2.多个按钮信息框
AlertDialog.Builder builder = new AlertDialog.Builder(MainDialog.this); builder.setIcon(R.drawable.icon); builder.setTitle("投票"); builder.setMessage("您认为什么样的内容能吸引您?"); builder.setPositiveButton("有趣味的", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { showDialog("你选择了有趣味的"); } }); builder.setNeutralButton("有思想的", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { showDialog("你选择了有思想的"); } }); builder.setNegativeButton("主题强的", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { showDialog("你选择了主题强的"); } }); builder.create().show();
3.列表框
这个数组用于列表选择
final String[] mItems = {"item0","item1","itme2","item3","itme4","item5","item6"}; AlertDialog.Builder builder = new AlertDialog.Builder(MainDialog.this); builder.setTitle("列表选择框"); builder.setItems(mItems, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { //点击后弹出窗口选择了第几项 showDialog("你选择的id为" + which + " , " + mItems[which]); } }); builder.create().show();
4.单项选择列表框
mSingleChoice 用于记录单选中的ID
int mSingleChoiceID = -1; AlertDialog.Builder builder = new AlertDialog.Builder(MainDialog.this); mSingleChoiceID = -1; builder.setIcon(R.drawable.icon); builder.setTitle("单项选择"); builder.setSingleChoiceItems(mItems, 0, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { mSingleChoiceID = whichButton; showDialog("你选择的id为" + whichButton + " , " + mItems[whichButton]); } }); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { if(mSingleChoiceID > 0) { showDialog("你选择的是" + mSingleChoiceID); } } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); builder.create().show();
5.进度条框
点击进度条框按钮后 开启一个线程计算读取的进度 假设读取结束为 100 Progress在小于100的时候一直在线程中做循环++ 只到读取结束后,停止线程。
mProgressDialog = new ProgressDialog(MainDialog.this); mProgressDialog.setIcon(R.drawable.icon); mProgressDialog.setTitle("进度条窗口"); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setMax(MAX_PROGRESS); mProgressDialog.setButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //这里添加点击后的逻辑 } }); mProgressDialog.setButton2("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //这里添加点击后的逻辑 } }); mProgressDialog.show(); new Thread(this).start(); public void run() { int Progress = 0; while(Progress < MAX_PROGRESS) { try { Thread.sleep(100); Progress++; mProgressDialog.incrementProgressBy(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
6.多项选择列表框
MultiChoiceID 用于记录多选选中的id号 存在ArrayList中 选中后 add 进ArrayList 取消选中后 remove 出ArrayList。
ArrayListMultiChoiceID = new ArrayList (); AlertDialog.Builder builder = new AlertDialog.Builder(MainDialog.this); MultiChoiceID.clear(); builder.setIcon(R.drawable.icon); builder.setTitle("多项选择"); builder.setMultiChoiceItems(mItems, new boolean[]{false, false, false, false, false, false, false}, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { if(isChecked) { MultiChoiceID.add(whichButton); showDialog("你选择的id为" + whichButton + " , " + mItems[whichButton]); }else { MultiChoiceID.remove(whichButton); } } }); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { String str = ""; int size = MultiChoiceID.size(); for (int i = 0 ;i < size; i++) { str+= mItems[MultiChoiceID.get(i)] + ", "; } showDialog("你选择的是" + str); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); builder.create().show();
7.自定义布局
讲到自定义布局我就得多说一说了,为什么要多说一说呢? 其实自定义布局在Android的开发中非常重要 因为它能让开发者做出自己五彩缤纷的Activity 而不用去使用系统枯燥的界面。
自定义dialog有什么好处?
比如我们在开发过长当中 要通过介绍系统发送的一个广播弹出一个dialog . 但是dialog必需是基于activity才能呈现出来 如果没有activity 的话 程序就会崩溃。所以我们可以写一个自定义的 dialog 把它定义成一个activity 这样我们收到一条打开dialog的广播后 直接启动这个 activity 程序正常运行~~
这就是自定义dialog的好处。
注明:下面这个例子只是写了自定义dialog 没有把它单独的写在一个activity中 如果须要的话 可以自己改一下。
AlertDialog.Builder builder = new AlertDialog.Builder(MainDialog.this); LayoutInflater factory = LayoutInflater.from(this); final View textEntryView = factory.inflate(R.layout.test, null); builder.setIcon(R.drawable.icon); builder.setTitle("自定义输入框"); builder.setView(textEntryView); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { EditText userName = (EditText) textEntryView.findViewById(R.id.etUserName); EditText password = (EditText) textEntryView.findViewById(R.id.etPassWord); showDialog("姓名 :" + userName.getText().toString() + "密码:" + password.getText().toString() ); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); builder.create().show();
8.读取进度框
显示一个正在转圈的进度条loading
mProgressDialog = new ProgressDialog(this); mProgressDialog.setTitle("读取ing"); mProgressDialog.setMessage("正在读取中请稍候"); mProgressDialog.setIndeterminate(true); mProgressDialog.setCancelable(true); mProgressDialog.show();
最后如果你还是觉得我写的不够详细 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习 雨松MOMO希望可以和大家一起进步。
下载地址:
自定义View界面大合集
雨松MOMO带大家盘点Android 中的自定义View界面的绘制
今天我用自己写的一个Demo 和大家详细介绍一个Android中自定义View中的使用与绘制技巧。
1.自定义view绘制字符串
相信在实际开发过程中必然很多地方都须要用到系统字 为什么会用到系统字? 方便 省内存 我相信做过J2ME游戏开发的朋友应该深知内存有多么多么重要 而且使用它还可以带来一个更重要的好处就是很方便的可以实现多国语言的切换 笔者现在在正在做的一个产品就是可以多语言切换的软件 有英语 繁体中文 等等 设想如果使用图片字的话那每个语言都须要出一套图,我用一个例子简单介绍一下绘制字符串。
1 package cn.m15.xys; 2 3 4 5 import android.app.Activity; 6 7 import android.content.Context; 8 9 import android.graphics.Canvas; 10 11 import android.graphics.Color; 12 13 import android.graphics.Paint; 14 15 import android.graphics.Paint.FontMetrics; 16 17 import android.os.Bundle; 18 19 import android.view.Display; 20 21 import android.view.View; 22 23 24 25 public class Font extends Activity { 26 27 public int mScreenWidth = 0; 28 29 public int mScreenHeight = 0; 30 31 @Override 32 33 protected void onCreate(Bundle savedInstanceState) { 34 35 setContentView(new FontView(this)); 36 37 // 获取屏幕宽高 38 39 Display display = getWindowManager().getDefaultDisplay(); 40 41 mScreenWidth = display.getWidth(); 42 43 mScreenHeight = display.getHeight(); 44 45 super.onCreate(savedInstanceState); 46 47 48 49 } 50 51 52 53 class FontView extends View { 54 55 public final static String STR_WIDTH = "获取字符串宽为:"; 56 57 public final static String STR_HEIGHT = "获取字体高度为:"; 58 59 Paint mPaint = null; 60 61 62 63 public FontView(Context context) { 64 65 super(context); 66 67 mPaint = new Paint(); 68 69 } 70 71 72 73 @Override 74 75 protected void onDraw(Canvas canvas) { 76 77 //设置字符串颜色 78 79 mPaint.setColor(Color.WHITE); 80 81 canvas.drawText("当前屏幕宽" + mScreenWidth, 0, 30, mPaint); 82 83 canvas.drawText("当前屏幕高"+ mScreenHeight, 0, 60, mPaint); 84 85 //设置字体大小 86 87 mPaint.setColor(Color.RED); 88 89 mPaint.setTextSize(18); 90 91 canvas.drawText("字体大小为18", 0, 90, mPaint); 92 93 //消除字体锯齿 94 95 mPaint.setFlags(Paint.ANTI_ALIAS_FLAG); 96 97 canvas.drawText("消除字体锯齿后", 0, 120, mPaint); 98 99 //获取字符串宽度100101 canvas.drawText(STR_WIDTH + getStringWidth(STR_WIDTH), 0, 150, mPaint);102103 //获取字体高度104105 canvas.drawText(STR_HEIGHT + getFontHeight(), 0, 180, mPaint);106107 //从string.xml读取字符串绘制108109 mPaint.setColor(Color.YELLOW);110111 canvas.drawText(getResources().getString(R.string.string_font), 0, 210, mPaint);112113 super.onDraw(canvas);114115 }116117118119 /**120121 * 获取字符串宽122123 * @param str124125 * @return126127 */128129 private int getStringWidth(String str) {130131 return (int) mPaint.measureText(STR_WIDTH);132133 }134135 /*136137 * 获取字体高度138139 */140141 private int getFontHeight() {142143 FontMetrics fm = mPaint.getFontMetrics();144145 return (int)Math.ceil(fm.descent - fm.top) + 2;146147 }148149 }150151 }
2.绘制无规则几何图形
绘制无规则几何图形似乎在实际工作中很少可以用到 原因是用程序去绘制图形即使在精准再好看也不会有美术出的图片好看 但是使用程序绘制图形作为学习来说却是基础中的基础,所以建议大家都看一看。
1 package cn.m15.xys; 2 3 4 5 import android.app.Activity; 6 7 import android.content.Context; 8 9 import android.graphics.Canvas; 10 11 import android.graphics.Color; 12 13 import android.graphics.Paint; 14 15 import android.graphics.Path; 16 17 import android.graphics.RectF; 18 19 import android.os.Bundle; 20 21 import android.view.View; 22 23 24 25 public class Geometry extends Activity { 26 27 public int mScreenWidth = 0; 28 29 public int mScreenHeight = 0; 30 31 32 33 @Override 34 35 protected void onCreate(Bundle savedInstanceState) { 36 37 setContentView(new GeometryView(this)); 38 39 super.onCreate(savedInstanceState); 40 41 42 43 } 44 45 46 47 class GeometryView extends View { 48 49 Paint mPaint = null; 50 51 52 53 public GeometryView(Context context) { 54 55 super(context); 56 57 mPaint = new Paint(); 58 59 mPaint.setFlags(Paint.ANTI_ALIAS_FLAG); 60 61 } 62 63 64 65 @Override 66 67 protected void onDraw(Canvas canvas) { 68 69 super.onDraw(canvas); 70 71 72 73 //设置画布颜色 也就是背景颜色 74 75 canvas.drawColor(Color.WHITE); 76 77 78 79 mPaint.setColor(Color.BLACK); 80 81 canvas.drawText("绘制无规则几何图形喔!!!", 150, 30, mPaint); 82 83 84 85 //绘制一条线 86 87 mPaint.setColor(Color.BLACK); 88 89 mPaint.setStrokeWidth(4); 90 91 canvas.drawLine(0, 0, 100, 100, mPaint); 92 93 94 95 //绘制一个矩形 96 97 mPaint.setColor(Color.YELLOW); 98 99 canvas.drawRect(0, 120, 100, 200, mPaint);100101102103 //绘制一个圆形104105 mPaint.setColor(Color.BLUE);106107 canvas.drawCircle(80, 300, 50, mPaint);108109110111 //绘制一个椭圆112113 mPaint.setColor(Color.CYAN);114115 canvas.drawOval(new RectF(300,370,120,100), mPaint);116117118119 //绘制多边形120121 mPaint.setColor(Color.BLACK);122123 Path path = new Path();124125 path.moveTo(150+5 , 400 -50);126127 path.lineTo(150+45, 400 - 50);128129 path.lineTo(150+30, 460 - 50);130131 path.lineTo(150+20, 460 - 50);132133 path.close();134135 canvas.drawPath(path, mPaint);136137138139 }140141 }142143 }
3.图片的绘制以及旋转缩放的实现
在这点上Android 确实比J2ME 强大很多 手机游戏开发最痛苦的是什么?? 是游戏引擎的开发,但是工程师会把大部分时间浪费在对坐标上,如果写引擎的时候没有把自适应考虑周全后期会非常痛苦,现在手机屏幕分辨率是各式各样 内存大小也是各式各样 所以可见自适应屏幕算法有多么的重要。
1 package cn.m15.xys; 2 3 4 5 import android.app.Activity; 6 7 import android.content.Context; 8 9 import android.graphics.Bitmap; 10 11 import android.graphics.BitmapFactory; 12 13 import android.graphics.Canvas; 14 15 import android.graphics.Matrix; 16 17 import android.graphics.Paint; 18 19 import android.os.Bundle; 20 21 import android.view.View; 22 23 import android.view.View.OnClickListener; 24 25 import android.widget.Button; 26 27 import android.widget.LinearLayout; 28 29 30 31 public class Image extends Activity { 32 33 ImageView imageView = null; 34 35 36 37 @Override 38 39 protected void onCreate(Bundle savedInstanceState) { 40 41 imageView = new ImageView(this); 42 43 setContentView(R.layout.image); 44 45 LinearLayout ll = (LinearLayout) findViewById(R.id.iamgeid); 46 47 ll.addView(imageView); 48 49 // 向左移动 50 51 Button botton0 = (Button) findViewById(R.id.buttonLeft); 52 53 botton0.setOnClickListener(new OnClickListener() { 54 55 @Override 56 57 public void onClick(View arg0) { 58 59 imageView.setPosLeft(); 60 61 } 62 63 }); 64 65 66 67 // 向右移动 68 69 Button botton1 = (Button) findViewById(R.id.buttonRight); 70 71 botton1.setOnClickListener(new OnClickListener() { 72 73 @Override 74 75 public void onClick(View arg0) { 76 77 imageView.setPosRight(); 78 79 } 80 81 }); 82 83 // 左旋转 84 85 Button botton2 = (Button) findViewById(R.id.buttonRotationLeft); 86 87 botton2.setOnClickListener(new OnClickListener() { 88 89 @Override 90 91 public void onClick(View arg0) { 92 93 imageView.setRotationLeft(); 94 95 } 96 97 }); 98 99100101 // 右旋转102103 Button botton3 = (Button) findViewById(R.id.buttonRotationRight);104105 botton3.setOnClickListener(new OnClickListener() {106107 @Override108109 public void onClick(View arg0) {110111 imageView.setRotationRight();112113 }114115 });116117118119 // 缩小120121 Button botton4 = (Button) findViewById(R.id.buttonNarrow);122123 botton4.setOnClickListener(new OnClickListener() {124125126127 @Override128129 public void onClick(View arg0) {130131 imageView.setNarrow();132133 }134135 });136137138139 // 放大140141 Button botton5 = (Button) findViewById(R.id.buttonEnlarge);142143 botton5.setOnClickListener(new OnClickListener() {144145146147 @Override148149 public void onClick(View arg0) {150151 imageView.setEnlarge();152153 }154155 });156157158159 super.onCreate(savedInstanceState);160161162163 }164165166167 class ImageView extends View {168169 Paint mPaint = null;170171 Bitmap bitMap = null;172173 Bitmap bitMapDisplay = null;174175 int m_posX = 120;176177 int m_posY = 50;178179 int m_bitMapWidth = 0;180181 int m_bitMapHeight = 0;182183 Matrix mMatrix = null;184185 float mAngle = 0.0f;186187 float mScale = 1f;//1为原图的大小188189190191 public ImageView(Context context) {192193 super(context);194195 mPaint = new Paint();196197 mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);198199 bitMap = BitmapFactory.decodeResource(this.getResources(),200201 R.drawable.image);202203 bitMapDisplay = bitMap;204205 mMatrix = new Matrix();206207 // 获取图片宽高208209 m_bitMapWidth = bitMap.getWidth();210211 m_bitMapHeight = bitMap.getHeight();212213 }214215216217 // 向左移动218219 public void setPosLeft() {220221 m_posX -= 10;222223 }224225226227 // 向右移动228229 public void setPosRight() {230231 m_posX += 10;232233 }234235236237 // 向左旋转238239 public void setRotationLeft() {240241 mAngle--;242243 setAngle();244245 }246247248249 // 向右旋转250251 public void setRotationRight() {252253 mAngle++;254255 setAngle();256257 }258259260261 // 缩小图片262263 public void setNarrow() {264265 if (mScale > 0.5) {266267 mScale -= 0.1;268269 setScale();270271 }272273 }274275276277 // 放大图片278279 public void setEnlarge() {280281 if (mScale < 2) {282283 mScale += 0.1;284285 setScale();286287 }288289 }290291292293 // 设置缩放比例294295 public void setAngle() {296297 mMatrix.reset();298299 mMatrix.setRotate(mAngle);300301 bitMapDisplay = Bitmap.createBitmap(bitMap, 0, 0, m_bitMapWidth,302303 m_bitMapHeight, mMatrix, true);304305 }306307308309 // 设置旋转比例310311 public void setScale() {312313 mMatrix.reset();314315 //float sx X轴缩放316317 //float sy Y轴缩放318319 mMatrix.postScale(mScale, mScale);320321 bitMapDisplay = Bitmap.createBitmap(bitMap, 0, 0, m_bitMapWidth,322323 m_bitMapHeight, mMatrix, true);324325 }326327328329 @Override330331 protected void onDraw(Canvas canvas) {332333 super.onDraw(canvas);334335 canvas.drawBitmap(bitMapDisplay, m_posX, m_posY, mPaint);336337 invalidate();338339 }340341 }342343 }
4.播放frame动画
做游戏的话播放动画可就是必不可少的元素 帧动画帧动画 顾名思义是一帧一帧的播放 。 实际在开发中为了节省内存美术会把人物的图片切成一小块一小块然后由程序根据编辑器生成的点把图片在拼接起来这样就可以做到用更少的图片去实现更多的动画 效果因为不太方便介绍图片编辑器 这个demo我只给大家简单的介绍一下播放动画的原理 后期我会深入讲解。 如图所示这个小人一直在行走 实际上是4张图片在来回切换 每张图片延迟500毫秒 后播下一张 以此类推。
package cn.m15.xys; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.view.View; public class FramAnimation extends Activity { public final static int ANIM_COUNT = 4; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(new FramView(this)); super.onCreate(savedInstanceState); } class FramView extends View { Bitmap[] bitmap = new Bitmap[ANIM_COUNT]; Bitmap display = null; Paint paint = null; long startTime = 0; int playID = 0; public FramView(Context context) { super(context); for (int i = 0; i < ANIM_COUNT; i++) { bitmap[i] = BitmapFactory.decodeResource(this.getResources(), R.drawable.hero_a + i); } display = bitmap[0]; paint = new Paint(); startTime = System.currentTimeMillis(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setColor(Color.WHITE); canvas.drawText("播放动画中...", 100, 30, paint); long nowTime = System.currentTimeMillis(); if (nowTime - startTime >= 500) { startTime=nowTime; playID++; if (playID >= ANIM_COUNT) { playID = 0; } canvas.drawBitmap(bitmap[playID], 100, 100, paint); } invalidate(); } }