1.toast

Toast toast = Toast.makeText(this, "自定义的toast", Toast.LENGTH_SHORT);toast.setGravity(Gravity.TOP, 30, 30);View view = LayoutInflater.from(this).inflate(R.layout.toast, null);toast.setView(view);toast.show();

2.Notification

mNotify = new Notification(R.drawable.icon, "通知", System.currentTimeMillis());// 正在运行,不允许被清除mNotify.flags = Notification.FLAG_ONGOING_EVENT;                 //震动mNotify.defaults |= Notification.DEFAULT_VIBRATE; long[] vibrates = new long[]{0, 100, 200, 300}; mNotify.vibrate = vibrates ;


声明震动权限<uses-permission android:name="android.permission.VIBRATE"></uses-permission> 注意模拟器没有震动功能,需要真机测试

// 定制intentIntent intent = new Intent(this, MyService.class);PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent,PendingIntent.FLAG_UPDATE_CURRENT);                mNotify.contentIntent = pendingIntent;// 自定义通知布局RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.updatenotify);mNotify.contentView = contentView;// 使用通知mNotifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);mNotifyMgr.notify(R.string.hello, mNotify);

//更新通知mNotify.contentView.setProgressBar(R.id.progressBar1, NOTITY_PROGRESS_MAX, progress, false);mNotifyMgr.notify(R.string.hello, mNotify);if (progress == NOTITY_PROGRESS_MAX) {Toast.makeText(this, "下载完成,请查看通知安装", Toast.LENGTH_SHORT).show();}

3.dialog

protected Dialog onCreateDialog(int id) {Dialog dialog = new Dialog(this);dialog.setContentView(R.layout.dialog);dialog.setTitle("标题");return dialog;}//在需要显示的地方写showDialog(1);

4.menu

自定义菜单,分析菜单的特征

什么条件下显示:按Menu

什么条件下关闭:
1) 当菜单显示时,再点击一次菜单按钮
2) 某一个菜单项被点击
3) back Activity不响应back
4) 其它Activity激活
5) 点击菜单和状态栏以外的区域
补充:当菜单存在时,点击菜单以外区域,界面不能响应用户操作
public class MainActivity extends Activity implements OnClickListener {private PopupWindow mOptionsMenu;private int[] menuItemIDs = new int[] { R.id.menuitem1, R.id.menuitem2, R.id.menuitem3,R.id.menuitem4, R.id.menuitem5, R.id.menuitem6, R.id.menuitem7, R.id.menuitem8,R.id.empty };@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);View contentView = LayoutInflater.from(this).inflate(R.layout.optionsmenu, null);mOptionsMenu = new PopupWindow(contentView, LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);initMenuItem(contentView);}@Overrideprotected void onPause() {super.onPause();closeMenuIfExist();}private boolean closeMenuIfExist() {if (mOptionsMenu.isShowing()) {mOptionsMenu.dismiss();return true;}return false;}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {if (closeMenuIfExist()) {return true;}}return super.onKeyDown(keyCode, event);}private void initMenuItem(View contentView) {for (int i = 0; i < menuItemIDs.length; i++) {contentView.findViewById(menuItemIDs[i]).setOnClickListener(this);}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {if (!closeMenuIfExist()) {mOptionsMenu.showAtLocation(findViewById(R.id.main), Gravity.BOTTOM, 0, 0);}return false;}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.menuitem1:Intent intent = new Intent();intent.setClass(this, Second.class);startActivity(intent);break;case R.id.menuitem2:break;case R.id.menuitem3:break;case R.id.menuitem4:break;case R.id.menuitem5:break;case R.id.menuitem6:break;case R.id.menuitem7:break;case R.id.menuitem8:break;case R.id.empty:break;default:break;}mOptionsMenu.dismiss();}}

注意,R.id.empty指的是菜单外面的view,可以用帧布局放置
可以用selector 为菜单设置点击效果
菜单项显示图片和文本
两类:
1) 图片和文本做成一张图片
2) GridView
布局嵌套


5.progress

<SeekBar                android:id="@+id/progress"                style="?android:attr/progressBarStyleHorizontal"                android:progressDrawable="@drawable/seek_background"                android:thumb="@drawable/thumb"                android:layout_width="346dip"                android:layout_height="32dip"                android:maxHeight="10dip"                android:paddingLeft="8dip"                android:paddingRight="8dip"                android:paddingTop="2dip"                android:paddingBottom="6dip"                android:max="1000"/><!--                android:minHeight="10dip"-->
seek_background.xml
<?xml version="1.0" encoding="UTF-8"?><layer-list  xmlns:android="http://schemas.android.com/apk/res/android">    <item android:id="@android:id/background" android:drawable="@drawable/time_line_bg" />    <item android:id="@android:id/progress" android:drawable="@drawable/progress_time" /></layer-list>

tumb.xml
<?xml version="1.0" encoding="UTF-8"?><selectorxmlns:android="http://schemas.android.com/apk/res/android"><!-- 按下状态 --><itemandroid:state_pressed="true"android:drawable="@drawable/drag_btn_down" /><!-- 普通无焦点状态 --><itemandroid:state_focused="false"android:state_pressed="false"android:drawable="@drawable/drag_btn" /></selector>



6.view

public class LabelView extends View {private Paint mTextPaint;private String mText;private int mAscent;/** * 定义一个构造器来初始化这个自定义的view,这个构造器可以在java代码中用来生成view 如 new LabelView(context) *  * @param context *            上下文 */public LabelView(Context context) {super(context);initLabelView();}/** * @param context *            上下文 * @param attrs *            从带styleable的xml中读到的属性 */public LabelView(Context context, AttributeSet attrs) {super(context, attrs);initLabelView();// 从R.styleable.LabelView文件中获得属性集合TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LabelView);// 通过typedArray.getString或者typedArray.getInt获得对应的属性设定的值// 属性的名称为styleable名称“LabelView”,加上“_”,再加上属性名称"text",组成“LabelView_text”CharSequence s = a.getString(R.styleable.LabelView_text);if (s != null) {// 设置text的contentsetText(s.toString());}// 设置text的color,如果没有设置,默认值为0xFF000000setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF000000));// 设置text的文字大小int textSize = a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0);if (textSize > 0) {setTextSize(textSize);}// 之前设置的属性,设置循环利用a.recycle();}/** * 新建画笔和设置画笔的样式 */private final void initLabelView() {mTextPaint = new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setTextSize(16);mTextPaint.setColor(0xFF000000);setPadding(3, 3, 3, 3);}/** * 设置文字内容,可以类外使用new view后,再使用view.setText设置内容,在构造器处被调用 * @param text */public void setText(String text) {mText = text;requestLayout();invalidate();}/**设置字体大小,在构造器处被调用 * @param size */public void setTextSize(int size) {mTextPaint.setTextSize(size);requestLayout();invalidate();}/**设置字体颜色,在构造器处被调用 * @param color */public void setTextColor(int color) {mTextPaint.setColor(color);invalidate();}/**设置自定义view的显示的大小 * @see android.view.View#onMeasure(int, int) */@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//measureWidth和measureHeight事自定义的两个用来设置宽度和高度的方法setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));}/** * 设置宽度,写法一般都遵循这样的框架,需要getMode和getSize来分辨用户设置的“match_parent”还是“wrap_content”等 * @param 具体的值          * @return 返回宽度 */private int measureWidth(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);if (specMode == MeasureSpec.EXACTLY) {// 确切地知道大小,即设置width=“123”等这些具体数值result = specSize;} else {// 这里相当于设置宽度为wrapContentresult = (int) mTextPaint.measureText(mText) + getPaddingLeft() + getPaddingRight();if (specMode == MeasureSpec.AT_MOST) {// 相当于设置成UNSPECIFIEDresult = Math.min(result, specSize);}}return result;}/** *与measureWidth方法类似 */private int measureHeight(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);mAscent = (int) mTextPaint.ascent();if (specMode == MeasureSpec.EXACTLY) {result = specSize;} else {result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop() + getPaddingBottom();if (specMode == MeasureSpec.AT_MOST) {result = Math.min(result, specSize);}}return result;}/** * 描述view的画法的一个方法,在invalidate时回调 */@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);}}

其中context.obtainStyledAttributes(attrs, R.styleable.LabelView);指的是从xml中获取属性集合
你可以新建一项位于values下的xml文件 resource下面包含以下代码

 <declare-styleable name="LabelView">        <attr format="string" name="text" />        <attr format="color" name="textColor" />        <attr format="dimension" name="textSize" />    </declare-styleable>

或者像这样写
<?xml version="1.0" encoding="UTF-8"?><resources>    <declare-styleable name="EditTextExt">        <attr name="Text" format="reference|string"></attr>        <attr name="Oriental">            <enum name="Horizontal" value="1"></enum>            <enum name="Vertical" value="0"></enum>        </attr>    </declare-styleable></resources>
上面里面有一个enum枚举两个选项,供用户只能在这两个选项中选一个,否则编译报错

分析measureWidth和measureHeight方法
依据specMode的值,(MeasureSpec有3种模式分别是UNSPECIFIED, EXACTLY和AT_MOST)

如果是AT_MOST,specSize 代表的是最大可获得的空间;

如果是EXACTLY,specSize 代表的是精确的尺寸;
如果是UNSPECIFIED,对于控件尺寸来说,没有任何参考意义。

那么这些模式和我们平时设置的layout参数fill_parent, wrap_content有什么关系呢?
经过代码测试就知道,当我们设置width或height为fill_parent时,容器在布局时调用子 view的measure方法传入的模式是EXACTLY,因为子view会占据剩余容器的空间,所以它大小是确定的。
而当设置为 wrap_content时,容器传进去的是AT_MOST, 表示子view的大小最多是多少,这样子view会根据这个上限来设置自己的尺寸。当子view的大小设置为精确值时,容器传入的是EXACTLY, 而MeasureSpec的UNSPECIFIED模式目前还没有发现在什么情况下使用。
View的onMeasure方法默认行为是当模式为UNSPECIFIED时,设置尺寸为mMinWidth(通常为0)或者背景drawable的最小尺寸,当模式为EXACTLY或者AT_MOST时,尺寸设置为传入的MeasureSpec的大小。
有个观念需要纠正的是,fill_parent应该是子view会占据剩下容器的空间,而不会覆盖前面已布局好的其他view空间,当然后面布局子 view就没有空间给分配了,所以fill_parent属性对布局顺序很重要。以前所想的是把所有容器的空间都占满了,难怪google在2.2版本里把fill_parent的名字改为match_parent.

  在两种情况下,你必须绝对的处理这些限制。在一些情况下,它可能会返回超出这些限制的尺寸,在这种情况下,你可以让父元素选择如何对待超出的View,使用裁剪还是滚动等技术。

最后,这个view就可以像平时我们在xml里面布局对待其他控件一样

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res/org.yuchen.customview"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="@string/hello" />    <org.yuchen.customview.LabelView        android:background="@drawable/blue"        android:layout_width="match_parent"        android:layout_height="wrap_content"        app:text="Blue"        app:textSize="20dp" />    <org.yuchen.customview.LabelView        android:background="@drawable/red"        android:layout_width="match_parent"        android:layout_height="wrap_content"        app:text="Red" /></LinearLayout>

注意需要有命名空间,所以你明白为什么我们每个xml布局都包含xmlns:android="http://schemas.android.com/apk/res/android"这句话了吧,因为用到android:layout_width等的引用
xmlns:app="http://schemas.android.com/apk/res/org.yuchen.customview"

 必须包含完整包名路径<org.yuchen.customview.LabelView
下面两个是我们在xml中自定义的两个属性
app:text="Blue"app:textSize="20dp"

自定义view还可以有第二种写法

package com.terry.attrs;import android.content.Context;import android.util.AttributeSet;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.TextView;public class EditTextExt1 extends LinearLayout {    private String Text = "";    public EditTextExt1(Context context) {        this(context, null);        // TODO Auto-generated constructor stub    }    public EditTextExt1(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        int resouceId = -1;        TextView tv = new TextView(context);         EditText et = new EditText(context);        resouceId = attrs.getAttributeResourceValue(null, "Text", 0);        if (resouceId > 0) {            Text = context.getResources().getText(resouceId).toString();        } else {            Text = "";        }        tv.setText(Text);        addView(tv);        addView(et, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,                LayoutParams.WRAP_CONTENT));        this.setGravity(LinearLayout.VERTICAL);    }}

这种写法,简单明了,不需要额外XML的配置,就可以在我们的VIEW文件下使用。

以上代码通过构造函数中引入的AttributeSet 去查找XML布局的属性名称,然后找到它对应引用的资源ID去找值。使用也时分方便。所以一直以来我也是很喜欢这种写法。

如上,自定好VIEW文件就可以在XML布局下如此使用:

<com.terry.attrs.EditTextExt1 android:id="@+id/ss3"        android:layout_width="wrap_content" android:layout_height="wrap_content"        Text="@string/app_name" ></com.terry.attrs.EditTextExt1>

部分代码参考自http://www.cnblogs.com/TerryBlog/archive/2010/11/03/1868431.html

更多相关文章

  1. Android如何自定义视图属性总结
  2. android : 控件在代码中设置属性-setWidth(int pixels)或setHeig
  3. Android布局文件-错误
  4. android用代码获取布局文件
  5. android RadioGroup与TabHost组合使用达到菜单效果
  6. 第十节(Activity布局初步三--相对布局)
  7. 控件布局_TableLayout
  8. Android View measure (五) 支持margin属性,从一个异常说起

随机推荐

  1. Android文件相关:RandomAccessFile介绍与
  2. Android(安卓)ClassLoader
  3. Android(安卓)Support V4, V7, V13的作用
  4. [置顶] android ANR
  5. Android(安卓)Studio下Ndk开发踩过的坑以
  6. android 数据存储之 SharedPreference
  7. Android实践之ScrollView中滑动冲突处理
  8. 2016总结+2017计划
  9. XposedHook:hook敏感函数
  10. Android(安卓)反编译