Android学习——UI高级组件三

Android学习——UI高级组件三

PopupWindow(弹出式窗口)

Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:AlertDialog位置固定,PopupWindow位置随意。
PopupWindow几个方法

showAsDropDown(View anchor)

相对某个控件的位置(正左下方),无偏移

showAsDropDown(View anchor,int xoff,int yoff)

相对某个控件位置,有偏移

showAtLocation(View parent , int gravity,int x,int y)

相对父控件的位置可以设置偏移和无偏移

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/show"
        android:text="显示弹出窗口"
        android:onClick="showWindow"/>

弹出窗口的布局

<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="修改"
        android:layout_weight="1"
        android:id="@+id/button_edit"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="删除"
        android:layout_weight="1"
        android:id="@+id/button_delete"/>

</LinearLayout>

package com.example.myapplication3;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.PopupWindow;

/*
* PopupWindow组件
* */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    //按钮事件方法
    public void showWindow(View v){
        View view=getLayoutInflater().inflate(R.layout.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.setOutsideTouchable(true);
        popupWindow.getBackground().setAlpha(100);
        popupWindow.setFocusable(true);
        popupWindow.setTouchable(true);
        popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

        //显示
        popupWindow.showAtLocation(v, Gravity.BOTTOM,0,0);

    }
}

在这里插入图片描述
获取屏幕尺寸大小

//获取屏幕尺寸方法
        DisplayMetrics md=new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(md);
        int width=md.widthPixels;
        int height=md.heightPixels;

Notification

应用常规界面外展示的消息

Notification普通通知(Notification drawer标准显示方式)
新建一个button按钮

<Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送一个普通通知"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:onClick="sendNotification1"/>

设置信息

package com.example.myapplication3;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
/*
*Notification
* */
public class Main2Activity extends AppCompatActivity {
    private static final int NID_1=0x1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

    }
    //发送一个普通的通知
    public void sendNotification1(View v){
//        Notification n=new Notification();//老版本 API 11 之前创建通知的方法

//        Notification.Builder builder=new Notification.Builder(this);//API 11 之后使用
        //v4支持包
        NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
        //设置相关属性
        builder.setSmallIcon(R.mipmap.ic_launcher);//设置小图标
        builder.setContentTitle("你有一条新消息");//设置标题
        builder.setContentText("天道酬勤,宁静致远");//设置通知内容
        //创建通知对象
        Notification n=builder.build();
        //获取系统的通知管理器,发送通知
        NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(NID_1,n);
    }
}

在这里插入图片描述在这里插入图片描述
其他属性及事件

builder.setAutoCancel(true);//自动取消
builder.setDefaults(Notification.DEFAULT_ALL);//设置呼吸灯、响铃、震动
builder.setNumber(10);//数据条数
builder.setTicker("新消息");
builder.setOngoing(true);//设置为常驻通知
//定义一个意图,当点击通知时,要打开一个界面(Activity)
        Intent intent=new Intent(this,Main3Activity.class);
        //参数:上下文,请求编码(没有),意图,创建PendingIntent的方式
//        PendingIntent.FLAG_NO_CREATE;//如果有就是用,没有创建
//        PendingIntent.FLAG_CANCEL_CURRENT;//取消当前的PI,创建新的
//        PendingIntent.FLAG_ONE_SHOT;//只是用一次
//        PendingIntent.FLAG_UPDATE_CURRENT;//如果有,更新Intent,没有就创建
        PendingIntent pi=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);

在Main3Activity关闭通知

//取消指定ID通知
        NotificationManager nm= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nm.cancel(Main2Activity.NID_1);

若要发送一条短消息给另一个界面
使用方法

        //发送一条短消息
Intent.putExtra("msg","天道酬勤,宁静致远");

在另一个Activity界面接收

		String msg=getIntent().getStringExtra("msg");
        TextView tv=findViewById(R.id.msg);

Notification大视图通知
设置按钮

<Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送一个大视图通知"
        android:layout_below="@id/button"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:onClick="sendNotification2"/>

方法

private static final int NID_2=0x2;
//大视图
    public void sendNotification2(View v){
        NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
        //设置相关属性
        builder.setSmallIcon(R.mipmap.ic_launcher);//设置小图标
        builder.setContentTitle("消息");//设置标题
        builder.setContentText("消息");//设置通知内容
        //设置大视图样式
        NotificationCompat.InboxStyle style=new NotificationCompat.InboxStyle();
        style.setBigContentTitle("静夜思");//大视图内容
        style.addLine("床前明月光,");
        style.addLine("疑是地上霜。");
        style.addLine("举头望明月,");
        style.addLine("低头思故乡。");
        builder.setStyle(style);
        style.setSummaryText("作者:李白");//提示文本
        builder.setNumber(5);
        Notification n=builder.build();
        NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(NID_2,n);
    }

在这里插入图片描述在这里插入图片描述
Notifications进度条通知 (显示一个已知长度的进度条指示器)
button

<Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送一个进度条通知"
        android:layout_below="@id/button2"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:onClick="sendNotification3"/>

方法

private static final int NID_3=0x3;
//进度条通知
    public void sendNotification3(View v){
        final NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
        //设置相关属性
        builder.setSmallIcon(R.mipmap.ic_launcher);//设置小图标
        builder.setContentTitle("更新中...");//设置标题
        builder.setContentText("正在由装逼模式更新至牛逼模式...");//设置通知内容
        builder.setProgress(100,5,false);
        final NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(NID_3,builder.build());

        //模拟更新的线程
        new Thread(new Runnable() {
            @Override
            public void run() {
//                int progress=0;
                for (int progress=0;progress<=100;progress+=5){
                    builder.setProgress(100,progress,false);
                    nm.notify(NID_3,builder.build());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                builder.setProgress(0,0,true);//设置不确定进度
                builder.setContentText("更新完成,由于机主逼格不够,正在返回菜鸟模式");
                nm.notify(NID_3,builder.build());
            }
        }).start();
    }

在这里插入图片描述在这里插入图片描述
自定义通知
自定义布局custom_layout.xml 支持的布局方式(FrameLayout、LinearLayout、RelatuveLayout)

<?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="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:adjustViewBounds="true"
        tools:srcCompat="@tools:sample/avatars" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="歌曲名称" />

    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="播放" />

    <Button
        android:id="@+id/button6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="下一首" />

</LinearLayout>
 //自定义视图通知
    public void sendNotification4(View v){
        final NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
        //设置相关属性
        builder.setSmallIcon(R.mipmap.ic_launcher);//设置小图标
        builder.setOngoing(true);
//        builder.setContentTitle("更新中...");//设置标题
//        builder.setContentText("正在由装逼模式更新至牛逼模式...");//设置通知内容
        //创建一个远程的视图
        RemoteViews views=new RemoteViews(getPackageName(),R.layout.custom_layout);

        views.setTextViewText(R.id.textView_song,"陷阱");//设置textview文本
//        views.setImageViewResource();//设置imageview图片
        views.setTextViewText(R.id.button_play,"暂停");
//        views.setOnClickPendingIntent();//设置按钮单击事件

        builder.setContent(views);
        builder.setTicker("Android播放器");
        NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(NID_4,builder.build());
    }

在这里插入图片描述

样式和主题

样式Style:是给view和window指定外观和格式的属性集合。样式能够指定如宽高、边距、字体颜色大小、背景等属性。样式被定义在一个与布局xml文件分开的xml资源文件中。应用在一个组件上。

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:text="@string/hello_world"
        android:textColor="@android:color/holo_blue_dark"
        android:textSize="35sp"
        android:background="#00ff00"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"
        android:textColor="@android:color/holo_blue_dark"
        android:textSize="35sp"
        android:background="#00ff00"/>

在value下的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_blue_dark</item>
        <item name="android:textSize">35sp</item>
        <item name="android:background">#00ff00</item>
    </style>

调用时

    <TextView
        style="@style/Textview_Style"
        android:text="@string/hello_world"
        //可继续添加属性,将会覆盖原来style中的属性值/>

在这里插入图片描述
ps:parent属性,继承一个系统样式或用xx.yy(xx为继承样式)
在这里插入图片描述
主题Theme:应用在整个Activity或应用程序的样式,而不是一个独立的View对象。当一个样式被用作主题时,Activity或应用程序中的每一个view对象都会使用它所支持的美国样式属性。
在清单文件中进行配置

<style name="MyAppTheme">
        <item name="android:textColor">#000000</item>
        <item name="android:textSize">60sp</item>
    </style>
<activity
            android:name=".Main4Activity"
            android:label="@string/title_activity_main4"
            android:theme="@style/MyAppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

同时Activity类中继承类修改为Activity
在这里插入图片描述

自定义组件

三种方式:1.组合现有Android默认提供的组件:继承ViewGroup或其子layout类等布局类进行组合;2.调整现有Android默认提供的组件:继承子类具体类;3.完全自定义:继承view基类,里面界面及事件完全由自己控制。

1.自定义组件实现步骤
配置xml属性资源文件values目录下attr.xml,在其中定义样式。

<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>

在自定义类中引用

package com.example.myapplication3;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

    private int textColor;
    private int 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= (int) 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,10,10,paint);
    }
}

使用自定义组件

<com.example.myapplication3.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView"
        app:textColor="#ff0000"
        app:textSize="16sp"
        app:text="威哥新浪微博:http://weibo.com/jianweima"/>

在这里插入图片描述
2.自定义组件Scrollview嵌套Listview的冲突
现在strings下定义一列数组,用于显示在ListView上

<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>
        <item>关谷神奇</item>
        <item>唐悠悠</item>
        <item>陆展博</item>
        <item>张伟</item>
    </string-array>

然后在布局文件中

<?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=".Main6Activity">

    <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="match_parent"
                android:entries="@array/names"></ListView>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/button"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/button1"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/button2"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/button3"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/button4"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/button5" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>

在这里插入图片描述
若直接在滚动条组件Scrollview下加上Listview,会出现Listview显示不全的问题,只会显示列表中第一个内容,所以需要另外自定义一个ListView类

package com.example.myapplication3;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;

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);
    }
}

然后调用自定义的listView

<com.example.myapplication3.MyListView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:entries="@array/names"></com.example.myapplication3.MyListView>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/UUUUUltraman/article/details/88736793