您的位置:首页 > 移动开发 > Android开发

Android高级应用开发(基础篇) - stage6 - 学习笔记(下)

2014-01-17 17:35 555 查看
创建菜单

一、创建方式

1、xml

(1)制作Menu.xml,并且把菜单选项都设置好

(2)Inflater压进来,显示



game_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/new_game"
android:icon="@drawable/ic_new_game"
android:title="@string/new_game"
android:showAsAction="ifRoom"/>
<item android:id="@+id/help"
android:icon="@drawable/ic_help"
android:title="@string/help" />
</menu>


android:id——A resource ID that's unique to the item, which allows the application can recognize the item when the user selects it.

android:icon——A reference to a drawable to use as the item's icon.

android:title——A reference to a string to use as the item's title.

android:showAsAction——Specifies when and how this item should appear as an action item in the action bar.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}


2、Menu.add()

@Override
public boolean onCreateOptionsMenu(Menu menu) {
//add(int i, int i1, int i2, java.lang.CharSequence charSequence);
menu.add(1, 1, 1, "add");
menu.add(1, 2, 2, "delete");
return super.onCreateOptionsMenu(menu);
}


Menu可以多级嵌套

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/file"
android:title="@string/file" >
<!-- "file" submenu -->
<menu>
<item android:id="@+id/create_new"
android:title="@string/create_new" />
<item android:id="@+id/open"
android:title="@string/open" />
</menu>
</item>
</menu>


二、菜单类别

1、OptionMenu:按Menu键弹出的菜单
2、ContextMenu:右键菜单:需要注册

Register the View to which the context menu should be associated by calling
registerForContextMenu() and pass it the View.

If your activity uses a ListView or GridView and you want each item to provide the same context menu,

register all items for a context menu by passing the ListView or GridView to registerForContextMenu().

Implement the onCreateContextMenu() method in your Activity or Fragment

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}


Implement onContextItemSelected().

@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit:
editNote(info.id);
return true;
case R.id.delete:
deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}


3、SubMenu(归在OptionMenu和ContextMenu中)

创建Dialog

Builder设计模式
当一个对象太复杂,而且不一定每一个都是构建时必须的
所以使用Builder去拼装,需要哪些拼装哪些
拼装好以后调用create,返回需要的对象



Builder斜体,表示的是一个抽象类
Director与Builder之间是一个聚合的关系

大部分内容去官网看吧,讲的忒详细了

说明:
setCancelable(),能否取消

官方推荐复写onCreateDialog方法,能通过id创建不同的dialog

查看Dialog源码



很像Activity,有WIndowManager
能看到样式的定义,也能看到为什么Dialog默认居中

查看Dialog子类AlertDialog的源码

create是AlertDialog内部类Builder的方法



看一下AlertDialog的构造器



AlertController是一个控制对象,是后面与set相关的各个对象属性的控制器

回头看Create方法
P是一系列的参数,将设定的属性都应用到AlertDialog上

看一下show方法



show也调用了create方法,所以AlertDialog不调用create直接show也是可以的

看其父类Dialog的show方法



可以看到Dialog中也有一个DecorView,也有WindowManager
最后设置完成后,发送一个消息sendShowMessage()

提醒

一、Toast

二、Notification

基本Notification操作步骤

1、通过getSystemServices得到NotificationManager对象

2、构造一个Notification实例

3、Notification设置最新事件信息

4、启动提醒

public class MainActivity extends Activity {

private NotificationManager mNotificationManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// ......

// 设置NotificationManager实例
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

// ......

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

// public Notification(int icon, java.lang.CharSequence tickerText, long when)
// 这个构造器中传入的都是顶部提示条不拉下的时候显示的内容(图标和文字)
Notification notification = new Notification(R.drawable.icon,
"you have a new message", System.currentTimeMillis() + 1000);

// Pending是等待的意思,PendingIntent的作用就是点击后要进行的操作
// PendingIntent没有构造函数,通过getActivity,getService等获得并传入相关Intent
// PendingIntent不是Intent
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,
0x123, new Intent(MainActivity.this, LoginActicity.class), 0);

notification.setLatestEventInfo(MainActivity.this, "Notification Title",
"Notification Content", pendingIntent);

// 还可以定义一些震动、声音、呼吸灯等

// 定义震动
long[] vib = {0, 200, 400, 600, 1000};
notification.vibrate = vib;

mNotificationManager.notify(123, notification);
}
});

}

@Override
protected void onStop() {
// 可以通过id清掉指定通知,也可以通过cancelAll清掉所有
mNotificationManager.cancel(123);
super.onStop();
}
}


用户还可以自定义自己的布局样式

// public Notification(int icon, java.lang.CharSequence tickerText, long when)
// 这个构造器中传入的都是顶部提示条不拉下的时候显示的内容(图标和文字)
Notification notification = new Notification(R.drawable.icon,
"you have a new message", System.currentTimeMillis() + 1000);

// Pending是等待的意思,PendingIntent的作用就是点击后要进行的操作
// PendingIntent没有构造函数,通过getActivity,getService等获得并传入相关Intent
// PendingIntent不是Intent
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,
0x123, new Intent(MainActivity.this, LoginActicity.class), 0);

//                notification.setLatestEventInfo(MainActivity.this, "Notification Title",
//                        "Notification Content", pendingIntent);

// 主要不要与setLatestEventInfo共存,不然会冲突(都是设置页面布局的)
// contentView设置RemoteView布局,contentIntent设置点击后的操作PendingIntent
notification.contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
notification.contentIntent = pendingIntent;

mNotificationManager.notify(123, notification);


PendingIntent是Singleton模式

样式

使用?调用样式表示如果找不到定义的样式可以使用默认样式

使用@调用样式表示确定要使用指定的样式

values下面不看文件名,而以标签名确定,所以把所有values放一个文件也没问题

<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="textRed">
<item name="android:textColor">@color/color_red</item>
</style>

<style name="textGreen">
<item name="android:textColor">@color/color_green</item>
</style>

<style name="textBlue">
<item name="android:textColor">@color/color_blue</item>
</style>

<color name="color_red">#ff0000</color>
<color name="color_green">#00ff00</color>
<color name="color_blue">#0000ff</color>

</resources>


之前建立水平进度条时发现是这样引用的



看到是一个attr的属性,进入源码values/attrs.xml中可以看到





这些attr是被包含在declare-styleable标签中的,后面跟着的format是类型



style可以应用到View上,也可以应用到Activity或者Application上

style也可以继承

<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="customTheme" parent="@android:style/TextAppearance">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>

</style>

<style name="customTheme.textRed">
<item name="android:textColor">@color/color_red</item>
</style>

<style name="customTheme.textGreen">
<item name="android:textColor">@color/color_green</item>
</style>

<style name="customTheme.textBlue">
<item name="android:textColor">@color/color_blue</item>
</style>

<color name="color_red">#ff0000</color>
<color name="color_green">#00ff00</color>
<color name="color_blue">#0000ff</color>

</resources>


首先customTheme继承了系统的样式,而textRed等继承了customTheme的样式

开发中应该多使用style,这样换肤的时候更加方便。

values文件夹可以加后缀,语言、版本等等,可以参考这里

自定义组件

分类

1、Customized Component

继承View,增加更多的属性和事件,纵向扩展

2、Compound Component

继承ViewGroup,把多个简单控件通过布局拼装一个复合控件,横向扩展

定义组件步骤

1、选择继承类,View或View的子类

2、类的初始化:新增属性和新增属性的初值设定

3、重载方法

(1)onDraw(), onMeasure()

(2)onKeyEvent():监听器+重载函数

public class MyButton extends Button {

// 定义一个接口对象,传入的接口实现对象赋到此处
private OnIconClickListener mOnIconClickListener;

public MyButton(Context context) {
super(context);
}

public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

// 定义一个监听接口
interface OnIconClickListener{
// 定义一个方法
public void onClick(String iconObject);
}

public void setOnIconClickListener(OnIconClickListener onIconClickListener){
mOnIconClickListener = onIconClickListener;
}

// 设定一个protected方法,供子类调用并在onKeyDown中调用这个方法
protected void onIconClick(String iconObject){

}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (mOnIconClickListener != null){
mOnIconClickListener.onClick("Hello");
onIconClick("Hello");
}
return super.onKeyDown(keyCode, event);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(5, 5, 25, 25, paint);

}

}


使用方式

1、layout中<包名+类名>

2、<View class="包名+类名" /> 可以容易在动态代码写控件中使用

如果是内部类<View class="包名+类名$内部类类名" />



原则:

1、如果只是本项目用,可以用inner class

2、如果打算商业发布,需要用单独的类文件

3、如果打算商业发布,不要用xml layout文件,而用动态代码生成
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: