8.常用控件_样式主题
%title some-other-knowledge
%toc
= Notification =
Notification: 通知, 通知是处于 systemui 进程里的, 当systemui进程退出时,
也就不会有通知了.
我们的程序弹出通知, 用户点击通知后, 执行的内容会再回到我们的程序中打开activity,
这个过程
不能使用普通的intent, 而是用 PendingIntent, 延期意图.
{{{class="brush:java"
public class MainActivity extends Activity {
private NotificationManager nm;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
}
// 通知是显示在一个系统应用里面的 如果系统应用 ui挂了,通知就不会出来了.
@SuppressWarnings("deprecation")
public void click(View view) {
/* // 下面这个新的api只能在3.0及以上运行, 所以一般不用
* Notification notification = new
Notification.Builder(this)
* .setContentTitle("消息到来了")
.setContentText("消息的内容")
* .setSmallIcon(R.drawable.notification)
*
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher))
* .build();
*/
// 使用较低版本的api, 这里的消息是通知到来时屏幕顶部那行很快消失的文字
Notification notification = new
Notification(R.drawable.ic_launcher,
"有新的消息到来了",
System.currentTimeMillis());
// notification 被点击后的行为, 这里是点击后自动取消掉
notification.flags =
Notification.FLAG_AUTO_CANCEL;
// notification 还有许多其他的参数, 自己看
// 创建一个意图, 用于指定点击notification后执行的动作,
这个意图是在我们的应用中创建的
// 但是它却要在通知栏这个应用中打开, 所以要使用延期意图
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:110"));
// 使用延期的意图把intent包装一下, 不立刻执行,
这个意图是在另外的一个应用(通知栏)里执行.
PendingIntent contentIntent =
PendingIntent.getActivity(this, 0, intent, 0);
//旧的api 一定要记得设置notification的一个参数,
这里的参数是显示在拉开通知栏之后显示的
notification.setLatestEventInfo(this,
"Day08Notification", "内容哈哈哈哈", contentIntent);
nm.notify(0, notification);
}
}
}}}
---------
为什么通知栏拉下来时后面的activity不会执行onPause, onStop?
---------
= 常用对话框 =
{{{class="brush:java"
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 确定取消对话框
public void dialog1(View v) {
OnClickListener listener = new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int
which) {
switch (which) {
case
DialogInterface.BUTTON_POSITIVE:
Toast.makeText(getApplicationContext(),
"确定被点击", Toast.LENGTH_SHORT).show();
break;
case
DialogInterface.BUTTON_NEGATIVE:
Toast.makeText(getApplicationContext(),
"取消被点击", Toast.LENGTH_SHORT).show();
break;
}
}
};
new AlertDialog.Builder(this)
.setTitle("确定删除吗")
.setMessage("将会删除选中条目")
.setPositiveButton("确定", listener)
.setNegativeButton("取消", listener)
//.setNeutralButton("稍候", listener)
.setCancelable(false)
.show();
}
// 单选对话框
public void dialog2(View v) {
final String[] items = {"苹果","香蕉","梨"};
OnClickListener listener = new OnClickListener()
{
int item = 0;
@Override
public void onClick(DialogInterface dialog, int
which) {
switch (which) {
case
DialogInterface.BUTTON_POSITIVE:
Toast.makeText(getApplicationContext(),
"选择了"+items[item], Toast.LENGTH_SHORT).show();
break;
case
DialogInterface.BUTTON_NEGATIVE:
Toast.makeText(getApplicationContext(),
"取消被点击", Toast.LENGTH_SHORT).show();
break;
default :
// which 是个int型的值,
可用作指定被点击的条目
item = which;
break;
}
}
};
new AlertDialog.Builder(this)
.setTitle("请选择")
.setSingleChoiceItems(items, 0,
listener)
.setPositiveButton("确定", listener)
.setNegativeButton("取消", listener)
//.setNeutralButton("", listener)
.setCancelable(false)
.show();
}
// 多选对话框
public void dialog3(View v) {
// 多选对话框需要两个数组, 一个为条目内容, 一个为是否选中
final String[] items =
{"苹果","香蕉","梨","西瓜","葫芦娃"};
final boolean[] checked = new boolean[5];
// 多选条目点击时
OnMultiChoiceClickListener multiListener = new
OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int
which, boolean isChecked) {
checked[which] = isChecked;
}
};
OnClickListener listener = new OnClickListener()
{
StringBuilder sb = new
StringBuilder();
@Override
public void onClick(DialogInterface dialog, int
which) {
switch (which) {
case
DialogInterface.BUTTON_POSITIVE:
for(int i=0; i<checked.length; i++)
{
if(checked[i]) {
sb.append(items[i] + "
");
}
}
Toast.makeText(getApplicationContext(),
"选择了" +sb.toString(),
Toast.LENGTH_SHORT).show();
break;
case
DialogInterface.BUTTON_NEGATIVE:
Toast.makeText(getApplicationContext(),
"取消被点击",
Toast.LENGTH_SHORT).show();
break;
}
}
};
new AlertDialog.Builder(this)
.setTitle("请选择")
.setMultiChoiceItems(items, checked,
multiListener)
.setPositiveButton("确定", listener)
.setNegativeButton("取消", listener)
//.setNeutralButton("", listener)
.setCancelable(false)
.show();
}
public void dialog4(View v) {
final ProgressDialog dialog = new
ProgressDialog(this);
dialog.setTitle("请稍后");
dialog.setCancelable(false);
dialog.show();
new Thread(){
public void run() {
try {
Thread.sleep(3000);
// 移除对话框
dialog.dismiss();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}.start();
}
// 带进度条的进度对话框
public void dialog5(View v) {
final ProgressDialog dialog = new
ProgressDialog(this);
dialog.setTitle("请稍后");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax(100);
dialog.setCancelable(false);
dialog.show();
// 也可以使用timer代替线程
new Timer().schedule(new TimerTask() {
int progress = 0;
@Override
public void run() {
dialog.setProgress(progress+=2);
if(progress==100)
dialog.dismiss();
}
}, 100, 100);
}
}
}}}
= 常用UI =
- CheckBox
CheckBox的使用很简单, 常用的方法如下
{{{class="brush:java"
checkBox1.isChecked() // 获取选中状态
// 设置选中状态改变的监听器
checkBox1.setOnCheckedChangeListener(new
OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton
buttonView,
boolean isChecked) {
Toast.makeText(getApplicationContext(), "是否被勾选" +
isChecked, 0)
.show();
}
});
}}}
- RadioGroup
单选框组, 比如 男, 女, 保密, 布局文件和代码如下:
{{{class="brush:xml"
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rb_male"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="男" />
<RadioButton
android:id="@+id/rb_female"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女" />
<RadioButton
android:id="@+id/rb_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保密" />
</RadioGroup>
}}}
{{{class="brush:java"
int id =
radioGroup1.getCheckedRadioButtonId();
switch (id) {
case R.id.rb_all: // 保密
Toast.makeText(this, "选择了:未知", 0).show();
break;
case R.id.rb_male: // 男
Toast.makeText(this, "男", 0).show();
break;
case R.id.rb_female: // 女
Toast.makeText(this, "女", 0).show();
break;
}
}}}
3. Spinner
Spinner下拉列表, 它的下拉选项是使用程序生成的, 需要配置一个布局文件, 这一点和ListView很类似,
其实二者是有"亲缘关系"的, 在用法上有相似之处
{{{class="brush:java"
Spinner spinner = (Spinner)
findViewById(R.id.spinner1);
ArrayAdapter<String> adapter = new
ArrayAdapter<String>(this,
R.layout.stylespinner, R.id.tv_item);
adapter.add("java");
adapter.add("dotNet");
adapter.add("php");
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?>
adapterView, View view,
int position, long id) {
String itemContent = (String)
adapterView
.getItemAtPosition(position);
System.out.println(itemContent+"被选择了");
}
@Override
public void onNothingSelected(AdapterView<?>
parent) {
System.out.println("没内容被选择了");
}
});
}}}
每个条目使用的布局文件如下:
{{{class="brush:xml"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
}}}
4. Menu
菜单其实严格来讲不是UI组件, 其布局文件也不是在layout目录下,
而是在res/menu/下.
在创建项目是, MainActivity里其实已经有生成menu的代码了.
{{{class="brush:xml"
<menu
xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/collect"
android:title="收藏此文章"/>
<item android:id="@+id/sina"
android:title="分享到新浪微博"/>
<item android:id="@+id/tencent"
android:title="分享到QQ空间"/>
</menu>
}}}
{{{class="brush:java"
@Override
public boolean onCreateOptionsMenu(Menu menu)
{ // 按菜单按钮时调用
getMenuInflater().inflate(R.menu.main,
menu); // 加载布局文件
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem
item) { // 当选中菜单项时调用
switch (item.getItemId()) {
case R.id.collect:
Toast.makeText(getApplicationContext(), "收藏此文章",
Toast.LENGTH_SHORT).show();
break;
case R.id.sina:
Toast.makeText(getApplicationContext(), "分享到新浪微博",
Toast.LENGTH_SHORT).show();
break;
case R.id.tencent:
Toast.makeText(getApplicationContext(), "分享到QQ空间",
Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
}}}
= 样式与主题 =
样式 style.xml 作用范围是控件
主题 其实也是在 style.xml 里定义, 但是作用范围是activity或者整个应用
= 国际化与屏幕适配 =
android 中的国际化是非常容易的. 只需要在res目录下创建多个目录如 values-zh-rCN,
values-zh-rTW,
values-en, 等等, 里面的String写上不同国家的文字即可.
在其他地方调用时注意要使用R文件中生成的id.
对于图片也是一样, drawable-en-rUS, drawable-fr-rFR, 等等,
里面的图片资源名字起的一样即可.
屏幕适配前面已经说过了, layout-land, layout-port 适用于横竖屏切换.
drawable-hdpi, drawable-ldpi, 等等则适用于不同屏幕分辨率. 注意, 即使是 .9 patch
图片, 也应该放在对应的文件夹里.
= 使用代码创建UI =
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL); for (int i = 0; i < 5; i++) {
TextView tv = new TextView(this);
tv.setText("Large Text"+i);
tv.setTextSize(20);
tv.setTextColor(Color.BLACK);
ll.addView(tv, LinearLayout.LayoutParams.WRAP_CONTENT,
50);
}
Button bt = new Button(this);
bt.setText("Button");
bt.setTextSize(16);
bt.setTextColor(Color.BLACK);
ll.addView(bt, LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
setContentView(ll);