热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android高级UI组件(三)

一、popupWindow1.AlertDialog和PopupWindow最关键的区别是AlertDialog不能指定显示位置,只能默认显示在屏幕最中间(当然也可以通过设置WindowManag

一、popupWindow

1.AlertDialog和PopupWindow最关键的区别是AlertDialog不能指定显示位置,只能默认显示在屏幕最中间(当然也可以通过设置WindowManager参数来改变位置)。而PopupWindow是可以指定显示位置的,更加灵活。

PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种。

按照参照物的不同,可以分为相对于莫个控件(Anchor锚)和相对于父控件

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

showSaDropDown(View anchor,int xoff ,int yoff)  :相对于空间的位置,有偏移

showAtLocation(View parent,int gravity, int x,int y):相对于父控件的位置(例如郑重眼Gravity.CENTER),可以设置偏移或无偏移

2.PopupWindow的相关函数

(1)构造函数

//方法一:  
public PopupWindow (Context context)  
//方法二:  
public PopupWindow(View contentView)  
//方法三:  
public PopupWindow(View contentView, int width, int height)  
//方法四:  
public PopupWindow(View contentView, int width, int height, boolean focusable)

 

要生成一个PopupWindow最基本的三个条件是一定要设置的:View contentView,int width,int height,少一个就不可能弹出PopupWindow,所以如果使用方法一构造PopupWindow,完整的构造代码是这样的:

View cOntentView= LayoutInflater.from(MainActivity.this).inflate
(R.layout.popuplayout, null);  
PopupWindwo popWnd = PopupWindow (context);  
popWnd.setContentView(contentView);  
popWnd.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);  
popWnd.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);  

 

(2)显示函数

//相对某个控件的位置(正左下方),无偏移  
showAsDropDown(View anchor):  
//相对某个控件的位置,有偏移;xoff表示x轴的偏移,正值表示向右,负值表示向左;yoff表示相对y轴的偏移,正值是向上,负值是向下;  
showAsDropDown(View anchor, int xoff, int yoff):  
//相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移  
showAtLocation(View parent, int gravity, int x, int y):  

 

(3)其他函数

public void dismiss()  
//另外几个函数,这里不讲其意义,下篇细讲  
public void setFocusable(boolean focusable)  
public void setTouchable(boolean touchable)  
public void setOutsideTouchable(boolean touchable)  
public void setBackgroundDrawable(Drawable background)  

 

setOutside Touchable(boolean touchable)

这个函数的意义是指PopupWindow以外的区域是否可点击,即如果店家PopupWindow以外的区域,PopupWindow是否会消失

private void showPopupWindow() {  
    View contentView = LayoutInflater.from(MainActivity.this).inflate(
R.layout.popuplayout, null);  
    mPopWindow = new PopupWindow(contentView);  
    mPopWindow.setWidth(ViewGroup.LayoutParams.FILL_PARENT);  
    mPopWindow.setHeight(ViewGroup.LayoutParams.FILL_PARENT);  
  
    //外部是否可以点击  
    mPopWindow.setBackgroundDrawable(new BitmapDrawable());  
    mPopWindow.setOutsideTouchable(true);  
  
    …………//各ITEM点击响应  
  
    mPopWindow.showAsDropDown(mMenuTv);  
  
}  

 

setBackgroundDrawable(Drawable background)

这个函数不知能设置背景,加上他之后,setOutsideTouchable()才会生效,而且,加上他后,PopupWindow才会对手机的返回按钮有响应,即点击手机返回按钮,可以关闭PopupWindow,如果不加将关闭PopupWindow所在的activity

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

 

二、Notification

是在常规界面之外展示的消息。当app让系统发送一个消息的时候,消息首先以图标的形式显示在通知栏。要查看消息的详情需要进入到通知抽屉(notificationdrawer)中查看。通知栏和通知抽屉都是系统层面控制的,你随时可以查看,不限制于app。

Notification的界面元素:

(1)普通视图

这种风格是notification drawer的标准显示方式。

(2)宽视图

指你的notification被展开的时候会显示更大的视图,这种风格是android4.1之后才有的新特性

创建一个Notification:

首先将Notification的一些UI信息及相关动作赋予NotificationCompat.Builder对象,然后通过NotificationCompat.Builder.build()来获得Notification对象自己,然后调用NotificationManager.notify()想系统转交这个通知。一个Notification对象需要包含以下内容:

小图标(setSmallIcon()获取)

标题(setContentTitle()获取)

详情文字(setContentText()获取)

其余内容是可选的

                //发送一个普通视图的通知
                //API11之前创建通知的方式
//                Notification notification = new Notification();
                //版本api11之后使用
//                Notification.Builder builder = new Notification.Builder(MainActivity.this);
                //v4支持包
                NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
                //设置相关的属性
                builder.setSmallIcon(R.mipmap.ic_launcher); //设置小图标
                builder.setContentTitle("测试"); //设置通知标题
                builder.setContentText("测试通知"); // 设置通知内容
                builder.setAutoCancel(true);  //设置自动清除
                builder.setDefaults(Notification.DEFAULT_ALL);
                builder.setNumber(10);
                builder.setTicker("新消息");
//                builder.setOngoing(true); //设置为常驻通知,不能被清除

                //设置单击的响应事件
                //定义一个意图,当点击通知时要打开一个界面(Activity)
                Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                //参数:上下文,请求编码,意图,创建PendingIntent的方式
//                PendingIntent.FLAG_CANCEL_CURRENT  取消当前的PI,创建新的
//                PendingIntent.FLAG_NO_CREATE  如果有就是用,没有就不创建
//                PendingIntent.FLAG_IMMUTABLE  只使用一次
//                PendingIntent.FLAG_UPDATE_CURRENT  如果有就更新Intent
                PendingIntent pi = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
                builder.setContentIntent(pi);

                //创建一个通知对象
                Notification notification = builder.build();
                //获取系统的通知管理器 ,然后发送
                NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                nm.notify(N_ID,notification);
public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        //打开界面取消指定ID的通知
        NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nm.cancel(MainActivity.N_ID);
    }
}

 

                //发送一个大视图的通知
                NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
                //设置相关的属性
                builder.setSmallIcon(R.mipmap.ic_launcher); //设置小图标
                builder.setContentTitle("测试"); //设置通知标题
                builder.setContentText("测试通知"); // 设置通知内容
                //设置大视图样式
                NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
                style.setBigContentTitle("测试测试");
                style.addLine("4444");
                style.addLine("5555");
                style.addLine("6666");
                builder.setStyle(style);

                Notification n = builder.build();
                NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                nm.notify(N_ID,n);
                //发送一个进度条的通知
                NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
                //设置相关的属性
                builder.setSmallIcon(R.mipmap.ic_launcher); //设置小图标
                builder.setContentTitle("测试"); //设置通知标题
                builder.setContentText("测试通知"); // 设置通知内容
                //设置进度条样式
                builder.setProgress(100,5,false);
                Notification n = builder.build();
                NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                nm.notify(N_ID,n);

 

                //发送一个进度条的通知
                final NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
                //设置相关的属性
                builder.setSmallIcon(R.mipmap.ic_launcher); //设置小图标
                builder.setContentTitle("测试"); //设置通知标题
                builder.setContentText("测试通知"); // 设置通知内容

                final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                nm.notify(N_ID, builder.build());
                //设置进度条样式

                //模拟更新的线程
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i <101; i++) {
                            builder.setProgress(100, i, false);
                            nm.notify(N_ID, builder.build());
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }

                        builder.setProgress(0, 0, false);
                        builder.setContentText("更新完成");
                        nm.notify(N_ID, builder.build());
                    }
                }).start();

            }
        });

 

                //发送一个自定义视图的通知
                NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
                builder.setSmallIcon(R.mipmap.ic_launcher);
                RemoteViews views = new RemoteViews(getPackageName(),R.layout.custom_layout);
                builder.setContent(views);
                builder.setTicker("测试");
                NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                nm.notify(N_ID1,builder.build());

三、 样式和主题

样式是给View或Window指定外观和格式的属性集合。样式能够指定如高、编剧、字体颜色、字体尺寸、背景颜色等属性。样式被定义在一个与布局XML文件分开的XML资源文件中。Android中的样式与Web设计中的层叠式列表类似,允许与内容分开设计。

样式(Style)

    

 

 

元素的每个子元素在编译时都要被转换成一个应用程序资源对象,通过元素的name属性值来引用,即使用@style/text_style来引用,元素中的parent属性是可选的,他指定了另一个样式的资源ID,当前样式可以季程程这个指定样式的属性,所以如果需要,可以覆写被继承的样式属性。把XML中定义的一个样式用作一个Activity或应用程序的主题与给一个View对象定义样式完全相同。如上面得样式能够被应用于一个View对象,也可用作一个Activity或应用程序的主题。

主题(Themes)

主题是应用于整个Activity或应用程序的样式,而不是一个独立的View对象,当一个样式被用做主题时,Activity或应用程序中的每个View对象都会使用它所支持的每个样式属性。例如,把相同的text_style样式用作一个Activity的主题,那么这个Activity内的所有文本的北京都是指定的北京。

 

实现自定义组件

配合XML属性资源文件的方式

第一步:attrs.xml文件

首先写出自定义组件的类文件,然后将这个类里需要外界传入值得属性定义成一个属性资源文件,在工程里的../res/values/目录下创建一个attrs.xml文件,具体写法如下:



    
        
        
        
    

 

attrs.xml解释如下

attrs子元素:

定义具体的属性,format表示这个属性的值的类型,类型有以下几种:

   reference:参考指定Theme中资源ID,这个类型意思就是你传的值可以使引用资源

  string:字符串,如果你想别人技能直接写值也可以用类似“@string/test”引用资源的方式,可以写成format="string|reference"

  color、boolean、dimension、float、integer、fraction(百分数)、

  enum:枚举

        
            <enum name="China" value="1" />
            <enum name="English" value="2" />
        

 

flag:位或运算

declare-styleable子元素:

 定义一个styleable对象,每个styleable对象就是一组attr属性的集合,注意:这里的name属性并不是一定要和自定义类名相同,只是为了好区分对应类的属性而已

第二步:在自定义类里引用attrs文件里定义的属性为自己的属性设置值。

    <com.gaochunfa.jiexidemo.MyView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:textColor="#ff0000"
        app:textSize="35sp"
        app:text="ssss"/>
package com.gaochunfa.jiexidemo;

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


public class MyView extends View{
    private Paint mPaint;
    private int textColor;
    private float textSize;
    private String text;
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        //这里去的declare-styleable集合
        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, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    //视图的绘制事件
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(textColor);
        mPaint.setTextSize(textSize);

        canvas.drawText(text,20,20,mPaint);
    }
}

 


推荐阅读
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 1简介本文结合数字信号处理课程和Matlab程序设计课程的相关知识,给出了基于Matlab的音乐播放器的总体设计方案,介绍了播放器主要模块的功能,设计与实现方法.我们将该设 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了如何使用elementui分页组件进行分页功能的改写,只需一行代码即可调用。通过封装分页组件,避免在每个页面都写跳转请求的重复代码。详细的代码示例和使用方法在正文中给出。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • SmartRefreshLayout自定义头部刷新和底部加载
    1.添加依赖implementation‘com.scwang.smartrefresh:SmartRefreshLayout:1.0.3’implementation‘com.s ... [详细]
  • 前端开发工程师必读书籍有哪些值得推荐?我们直接进入代码复杂版式设置,如下所示,先写些标签,源码在这个链接里面:https://codepen.io/Shadid ... [详细]
  • 我收到这个错误.我怎么能在我的情况下解决这个问题?Bitmapcannotberesolvedtoatype发生错误的行publicvoidonPageStart ... [详细]
author-avatar
黑天鹅猪猪_251
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有