PopupWindow(以弹窗方式呈现组件)
在MainActivity中记得设置ID,用来给各事件获取对应的值
public static final int NID_1=0x1;
public static final int NID_2=0x2;
public static final int NID_3=0x3;
public static final int NID_4=0x4;
在activity文件中设置一个按钮,用来点击呈现效果
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show"
android:text="显示弹出窗口"
android:onClick="showWindow"/>
新建一个布局文件popup_window_layout,内容如下,用于点击按钮后显示
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/button_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="编辑" />
<Button
android:id="@+id/button2_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除" />
</LinearLayout>
在MainActivity文件中实现按钮点击事件
//按钮事件方法
public void showWindow(View v){
View view=getLayoutInflater().inflate(R.layout.popup_window_layout,null);
//创建PopupWindow(相对的视图控件,宽,高)
PopupWindow popupWindow=new PopupWindow(view,
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.btn_default));
popupWindow.setAnimationStyle(android.R.style.Animation_Translucent);
popupWindow.getBackground().setAlpha(100); //背景透明度
popupWindow.setOutsideTouchable(true); //点击弹窗外任意处弹窗消失
popupWindow.setFocusable(true); //获得焦点
popupWindow.setTouchable(true); //设置是否响应点击事件
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//
popupWindow.showAtLocation(v, Gravity.BOTTOM,0,0); //显示的位置
//获取屏幕尺寸
DisplayMetrics dm=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width= dm.widthPixels;
int height=dm.heightPixels;
}
测试效果如下
Notification(通知)
在布局文件中放置按钮用来点击呈现效果
<Button
android:id="@+id/button_normal_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="5dp"
android:onClick="sendNotification1"
android:text="发送一个普通的通知" />
<Button
android:id="@+id/button2_big_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="53dp"
android:onClick="sendNotification2"
android:text="发送一个大视图的通知" />
<Button
android:id="@+id/button3_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="113dp"
android:onClick="sendNotification3"
android:text="发送一个进度条的通知" />
<Button
android:id="@+id/button4_custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:onClick="sendNotification4"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="176dp"
android:text="发送一个自定义视图的通知" />
设置按钮一的点击事件(发送一个普通的通知)
//发送一个普通的通知
public void sendNotification1(View v){
//API 11之前创建通知的方式
// Notification n=new Notification();
//API 11 之后
// Notification.Builder builder=new Notification.Builder(this);
//v4支持包
NotificationCompat.Builder builder1=new NotificationCompat.Builder(this);
//设置相关的属性
builder1.setSmallIcon(R.mipmap.ic_launcher);//设置图标
builder1.setContentTitle("你有一条新消息");
builder1.setContentText("新年快乐!万事如意!");
// builder1.setAutoCancel(true);//点击后自动取消通知
builder1.setDefaults(Notification.DEFAULT_ALL);
builder1.setNumber(10);
builder1.setTicker("新消息");
// builder1.setOngoing(true);//设置为常驻通知
//定义一个意图,当点击通知时,要打开一个界面(Activity)
Intent intent=new Intent(this,Main2Activity.class);
intent.putExtra("msg","新年快乐!万事如意!");
//参数:上下文,请求编码,意图,创建PendingIntet的方式
// PendingIntent.FLAG_CANCEL_CURRENT:取消当前的PI,创建新的
// PendingIntent.FLAG_NO_CREATE:如果有就用,没有不创建
// PendingIntent.FLAG_ONE_SHOT:只使用一次
// PendingIntent.FLAG_UPDATE_CURRENT:如果有,更新Intent,没有就创建
PendingIntent pi=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
//通知的事件
builder1.setContentIntent(pi);
//创建一个通知对象
Notification n=builder1.build();
//获取系统的通知管理器,然后发送
NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NID_1,n);
}
新建一个Main2Activity,但点击通知时显示,activity2中代码如下
<TextView
android:id="@+id/msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="144dp"
android:layout_marginTop="315dp"
android:text="Hello,新年快乐" />
测试效果如下
设置按钮2的点击事件(发送一个大视图的通知)
//大视图的通知
public void sendNotification2(View v){
NotificationCompat.Builder builder1=new NotificationCompat.Builder(this);
//设置相关的属性
builder1.setSmallIcon(R.mipmap.ic_launcher);//设置图标
builder1.setContentTitle("消息");
builder1.setContentText("消息");
//设置大视图样式
NotificationCompat.InboxStyle style=new NotificationCompat.InboxStyle();
style.setBigContentTitle("霹雳语录");
style.addLine("半神半圣亦半仙");
style.addLine("全儒全道是全贤");
style.addLine("脑中真书藏万卷");
style.addLine("掌握文武半边天");
builder1.setStyle(style);
style.setSummaryText("素还真");
builder1.setNumber(5);
Notification n=builder1.build();
NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NID_2,n);
}
测试效果如下
设置按钮3的点击事件(发送一个带进度条的通知)
//显示进度条的通知
public void sendNotification3(View v){
final NotificationCompat.Builder builder1=new NotificationCompat.Builder(this);
//设置相关的属性
builder1.setSmallIcon(R.mipmap.ic_launcher);//设置图标
builder1.setContentTitle("更新中...");
builder1.setContentText("正在由装逼模式更新至牛逼模式");
builder1.setProgress(100,5,false);
final NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NID_3,builder1.build());
//模拟更新的线程
new Thread(new Runnable() {
@Override
public void run() {
for(int progress=0;progress<=100;progress+=5){
builder1.setProgress(100,progress,false);
nm.notify(NID_3,builder1.build());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
builder1.setProgress(0,0,false);
builder1.setContentText("更新完成,由于机主逼格不够,正在返回逗逼模式");
nm.notify(NID_3,builder1.build());
}
}).start();
}
测试效果如下
设置按钮4的点击事件(发送一个自定义视图的通知)
public void sendNotification4(View v){
final NotificationCompat.Builder builder1=new NotificationCompat.Builder(this);
//设置相关的属性
builder1.setSmallIcon(R.mipmap.ic_launcher);//设置图标
builder1.setOngoing(true);
//创建一个远程的视图
RemoteViews views=new RemoteViews(getPackageName(),R.layout.custom_layout);
views.setTextViewText(R.id.textView_song_name,"夜雨寄北");
views.setTextViewText(R.id.button_play,"暂停");
// views.setOnClickPendingIntent();//设置按钮的单击事件
builder1.setContent(views);
builder1.setTicker("霹雳音乐");
NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NID_4,builder1.build());
}
新建一个视图custom_layout,代码如下
<?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-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="64dp"
android:maxWidth="64dp"
android:layout_weight="1"
android:adjustViewBounds="true"
app:srcCompat="@mipmap/ic_launcher_round" />
<TextView
android:id="@+id/textView_song_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="歌曲名称..." />
<Button
android:id="@+id/button_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="播放" />
<Button
android:id="@+id/button2_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下一首" />
</LinearLayout>
测试效果如下,由于虚拟机版本问题,所以这里图标没能显示出来
Style(样式)
通过在style文件中设置样式
<style name="TextView_Style" >
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">@android:color/holo_orange_light</item>
<item name="android:textSize">35sp</item>
<item name="android:background">@android:color/darker_gray</item>
</style>
<style name="TextView_Style.button"> //继承TextView_Style 样式
<item name="android:textSize">50sp</item>
在组件中直接获取style中设置的样式
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="@android:color/holo_orange_light"
android:textSize="35sp"
android:background="@android:color/darker_gray" />
<TextView
style="@style/TextView_Style"
android:text="Hello World!"
/>
<Button
style="@style/TextView_Style.button" android:text="按钮" />
在Style文件中设置样式
<style name="MyAppTheme">
<item name="android:textColor">#F11B0C</item>
<item name="android:textSize">60sp</item>
</style>
在清单文件(AndroidManifest)中设置主题
<activity android:name=".MainActivity"
android:theme="@style/MyAppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在activity文件中放置一个组件,不设置主题拥有的样式
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="主题样式测试"/>
测试效果
自定义组件
在res/values文件夹下创建一个attrs.xml文件,代码如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView">
<attr name="textColor" format="color"></attr>
<attr name="textSize" format="dimension"></attr>
<attr name="text" format="string"></attr>
</declare-styleable>
</resources>
新建一个MyView.java文件,代码如下
public class MyView extends View {
private int textColor;
private float textSize;
private String text;
private Paint paint;//画笔
public MyView(Context context) {
super(context);
}
public MyView(Context context,AttributeSet attrs) {
super(context, attrs);
paint=new Paint();
//获取配置文件中的属性值
TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.MyView);
textColor=array.getColor(R.styleable.MyView_textColor,0xFFFFFF);
textSize=array.getDimension(R.styleable.MyView_textSize,24);
text=array.getString(R.styleable.MyView_text);
}
public MyView(Context context,AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//视图的绘制事件方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(textColor);
paint.setTextSize(textSize);
canvas.drawText(text,100,400,paint);
}
}
在activity文件中设置组件,代码如下
<?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-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10sp"
android:text="自定义组件"/>
<com.example.customview.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:textColor="#ff0000"
app:textSize="30sp"
app:text="霹雳布袋戏"/>
</LinearLayout>
测试效果如下
ScrollView和listView组件嵌套使用冲突
activity代码如下
<?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-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/names">
</ListView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
strings文件代码如下
<string-array name="names">
<item>一页书</item>
<item>素还真</item>
<item>叶小钗</item>
<item>疏楼龙宿</item>
<item>剑子仙迹</item>
<item>赮毕钵罗</item>
<item>苍</item>
<item>萧中剑</item>
<item>佛剑分说</item>
<item>吞佛童子</item>
<item>一步莲华</item>
<item>策马天下</item>
<item>白马纵横</item>
<item>羽人非獍</item>
</string-array>
测试效果如下
listView只显示第一条数据
解决方案,自定义一个ListView组件
新建一个MyListView.java文件,代码如下
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec=MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
将activity中的ListView组件改成我们自己定义的MyListView组件
<com.example.customview.MyListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/names">
</com.example.customview.MyListView>
测试效果如下