Android5.0常用颜色属性说明
在使用Eclipse的时代,我们很少去在style文件给整个应用或者Activity去设定颜色,那是因为即使设置也不会提升用户的视觉效果。但是材料设计号称让没有设计功底的人也能做出漂亮的App,那我们今天就来看看在Androi5.0中常用的颜色属性。
我们可以先定义一个style,然后在这个style中设定每一个Activity或者整个App的颜色,最后在清单文件中来给某个Activity设置主题即可。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<style name="AppTheme.NoActionBar">
<!--状态栏颜色-->
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!--控制各个控件被选中时的颜色-->
<item name="colorAccent">@color/colorAccent</item>
<!--页面背景色-->
<item name="android:windowBackground">@color/windowBackg</item>
<!--底部导航栏颜色-->
<item name="android:navigationBarColor">@color/navigationColor</item>
<!--Appbar背景色-->
<item name="android:colorPrimary">@color/colorPrimary</item>
<!--ToolBar上的Title颜色-->
<item name="android:textColorPrimary">@color/textColorPrimary</item>
<!--各个控制控件的默认颜色-->
<item name="android:colorControlNormal">@color/colorControlNormal</ item>
</style>
|
最后再来一张图详细说明每个item设定的到底是哪里的颜色:
ConstraintLayout基本使用之toLeftOf 、toTopOf、toRightOf、toBottomOf
关于ConstraintLayout的博客、文章想必大家已经见过很多了,都是很全面的,今天这篇博客主要将ConstraintLayout的
1
2
3
4
|
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintTop_toTopOf
...
|
以上到底怎么理解呢?下面我将通过图片+文字来解释。
现在假设屏幕中间有个长宽为100dp的红色正方形,屏幕左上方有个宽高为50dp的黑色正方形,如下:
接下来我们一个一个试试这些参数吧!
1、layout_constraintLeft_toLeftOf(可以看出黑色正方形左边和红色正方形左边对齐)
2、layout_constraintLeft_toRightOf(黑色正方形的左边和红色正方形的右边对齐)
3、layout_constraintRight_toLeftOf(黑右对齐红左)
4、layout_constraintRight_toRightOf(黑右对齐红右)
剩余四个:
1
2
3
4
|
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
|
也是同理。
让我们看一下这个参数的统一命名:layout_constraintA_toBOf,
也即代表当前布局的A方向,对齐目标布局的B方向
Android 沉浸式标题栏设置,顶部view到状态栏
Android 沉浸式标题栏设置,顶部view到状态栏
布局xml文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent">
<TextView
android:id="@+id/tv_top_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:maxHeight="140dp"
android:background="@drawable/case_resource_transport_top_bg"
app:layout_constraintTop_toTopOf="parent" />
...
</android.support.constraint.ConstraintLayout>
|
activity AndroidManifest设置
1
2
3
4
|
<activity android:name="....xxActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.imgFullScreen"
android:windowSoftInputMode="adjustPan"/>
|
stayles.xml 添加style
1
2
3
4
5
|
<style name="AppTheme.imgFullScreen">
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">false</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
|
xxActivity添加
1
2
3
4
5
|
val decorView = window.decorView
val option = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
decorView.systemUiVisibility = option
window.statusBarColor = Color.TRANSPARENT
|
效果:
Android去除顶部默认的标题栏
当我们在Android Studio中创建一个新的Android项目时,会发现顶部有一个标题栏。我们有的时候并不需要这个标题栏,因此我们就需要把它去掉。
在Android Studio中展开Project模块,会看到里面是一个由文件和文件夹构成的树形图。打开里面的app->manifests->AndroidManifest.xml文件,然后找到application标签的android:theme属性,把它的值改为"@style/Theme.AppCompat.NoActionBar",这样就可以解决问题了。
Android注册服务
broadcastReceiver使用时需要在AndroidManifest.xml注册格式为
1
2
3
4
5
|
package="com">
<activity android:name=".MainActivity">
……
</activity>
<service android:name=".XXX" />
|
此处.目录取决于上面package导入的目录
Android TextView 文字居中
有2种方法可以设置TextView文字居中:
一:在xml文件设置:android:gravity=“center”
二:在程序中设置:m_TxtTitle.setGravity(Gravity.CENTER);
android给View设置上下左右边框
需求
设置view上下右有边框(左边不要边框),右上角右下角需要设置为圆角(左边不需要)
实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the main color -->
<item>
<shape>
<!-- 边框颜色 -->
<solid android:color="@color/flash_text_normal"/>
</shape>
</item>
<!-- 给View的上 下 右设置8dp的边框 -->
<!-- http://blog.csdn.net/lowprofile_coding/article/details/47848245-->
<item android:top="1dip" android:bottom="1dip" android:right="1dip" >
<shape>
<!-- View填充颜色 -->
<solid android:color="@color/public_round_yellow" />
<corners
android:topRightRadius="@dimen/x10"
android:bottomRightRadius="@dimen/x10" />
</shape>
</item>
</layer-list>
|
android 为TextView添加边框
今天需要在TextView上面添加一个边框,但是TextView本身不支持边框,所以只能采用其他方式,在网上查询了一下,主要有三种方式可以实现1.带有边框的透明图片2.使用xml的shape设置3继承TextView覆写onDraw方法。
方法一
带有透明图片的背景图,这个没有什么好将的,自己制作一个就行 ,然后设置background就可以了
方法二
1
2
3
4
5
|
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>
|
- 为要添加边框的TextView添加一个background
android:background="@drawable/textview_border"
效果图片如下:
方法三
编写一个继承TextView类的自定义组件,并在onDraw事件方法中画边框。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package com.example.test;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;
@SuppressLint("DrawAllocation")
public class BorderTextView extends TextView{
public BorderTextView(Context context) {
super(context);
}
public BorderTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
private int sroke_width = 1;
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
// 将边框设为黑色
paint.setColor(android.graphics.Color.BLACK);
// 画TextView的4个边
canvas.drawLine(0, 0, this.getWidth() - sroke_width, 0, paint);
canvas.drawLine(0, 0, 0, this.getHeight() - sroke_width, paint);
canvas.drawLine(this.getWidth() - sroke_width, 0, this.getWidth() - sroke_width, this.getHeight() - sroke_width, paint);
canvas.drawLine(0, this.getHeight() - sroke_width, this.getWidth() - sroke_width, this.getHeight() - sroke_width, paint);
super.onDraw(canvas);
}
}
|
效果图如下:
使用的Xml布局内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="120dp"
android:layout_height="80dp"
android:background="@drawable/textview_border"
android:text="方法二"
android:textColor="#FF000000"
android:id="@+id/test"
android:gravity="center"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
android:layout_centerHorizontal="true"/>
<com.example.test.BorderTextView
android:layout_width="120dp"
android:layout_height="80dp"
android:text="方法三"
android:id="@+id/test3"
android:gravity="center"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:layout_centerHorizontal="true">
</com.example.test.BorderTextView>
</RelativeLayout>
|
全局变量
切换Fragment时有些值需要保存,故需要一个全局变量进行保存
项目开发的过程中,可能会大量的使用全局变量,在android开发中,大多数人更偏向于使用application来保存全局变量。那么我们就先来了解下在android中,application究竟是什么?有什么作用?
Application类是用来维护应用程序全局状态。我们可以提供自己的实现,并在AndroidManifest.xml文件的标签中指出它的名字,这将导致在创建应用程序时去实例化我们自己的Application类。Android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例模式的一个类。且Application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局唯一的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以,通过Application来进行一些数据传递、数据共享、数据缓存等操作。
首先创建继承自Application的MusicPlayerStatus类,定义变量update、current,并创建get和set方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import android.app.Application;
public class MusicPlayerStatus extends Application {
private int update=-1;
private int current=-1;
public int getUpdate() {
return update;
}
public void setUpdate(int update) {
this.update = update;
}
public int getCurrent() {
return current;
}
public void setCurrent(int current) {
this.current = current;
}
}
|
下面就是如何使用我们创建的全局变量了,在MainActivity中,首先要获得MusicPlayerStatus的对象,因为MusicPlayerStatus继承自Application,所以使用getApplication()方法即可,然后可以调用MusicPlayerStatus的get或set方法进行访问全局变量。
1
2
3
4
5
|
public MusicPlayerStatus musicPlayerStatus=new MusicPlayerStatus();
int update = musicPlayerStatus.getUpdate();
int current = musicPlayerStatus.getCurrent();
musicPlayerStatus.setUpdate(update);
musicPlayerStatus.setCurrent(current);
|
注意,在使用MusicPlayerStatus之前需要修改AndroidManifest.xml文件的中的android:name = “.MusicPlayerStatus”,这样就不会访问系统提供的application,而访问我们自己创建的。
Android 使控件各占屏幕的一半
在xml中将两个要占屏幕一半的控件都加上android:layout_weight=“1”;
注意:weight只能用在LinearLayout布局中。
在LinearLayout布局中weight数值越大显示的优先权就越低。
Fragment生命周期
相互切换时调用的方法
一、前言:
Fragment生命周期图如下:
二、Fragment 1 切换到 Fragment 2时生命周期变化
1. 通过 add hide show 方式来切换 Fragment
- Fragment1 的生命周期变化为:onCreate()、onCreateView、onStart()、onResume() 回调 onHiddenChanged() 方法
- Fragment2 的生命周期变化为: onCreate()、onCreateView、onStart()、onResume()
- Fragment 2 再次返回到 Fragment 1:不走任何生命周期方法但是回调 onHiddenChanged()方法
总结:当以这种方式进行 Fragment 1 与 Fragment 2 的切换时,Fragment 隐藏的时候并不走 onDestroyView,所有的显示也不会走 onCreateView 方法,所有的 view 都会保存在内存。
2. 使用 replace 的方法进行切换时
- 载入Fragment 1时:
Fragment 1的生命周期:onCreate()、onCreateView()、onStart()、onResume()
- 切换到Fragment2时:
Fragment 1的生命周期:onPause()、onStop()、onDestroyView()、onDestroy()
Fragment 2的生命周期:onCreate()、onCreateV()、onStart()、onResume()
- Fragment 2切换回Fragment 1时:
Fragment2的生命周期:onPause()、onStop()、onDestroyView()、onDestroy()
Fragment 1的生命周期:onCreate()、onCreateV()、onStart()、onResume()
总结:通过 replace 方法进行替换的时,Fragment 都是进行了销毁,重建的过程,相当于走了一整套的生命周期。
当使用 ViewPager 与 Fragment 进行切换时,Fragment 会进行预加载操作
所有的 Fragment 都会提前初始—>预加载;
初始化时 Fragment 们的生命周期:
Fragment 1 的生命周期:onCreate()、onCreateView()
Fragment 2 的生命周期:onCreate()、 onCreateView()
- Fragment 1 切换到 Fragment 2 的生命周期:
Fragment 1 :不走任何生命周期;
Fragment 2 :走 setUserVisVleHint()方法
切回去也是一样的
注意: setUserVisVleHint()方法在 Fragment 1 第一次加载的时候不走,只有在切换的时候 走该方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/**
*第一个 Fragment 需要处理 setUserVisVleHint()方法,设置为 setUserVisibleHint(true);
*否则会产空指针异常,因为 setUserVisVleHint()方法的优先级高于 onCreate()方法。
*
* @param savedInstanceState
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
setUserVisibleHint(true);
super.onActivityCreated(savedInstanceState);
}
/*
主动调用 setUserVisibleHint()方法来控制第一次不会调用setUserVisibleHint方法的问题。
setUserVisibleHint()方法优先onCreateView方法,当onCreateView方法调用后还会再次调用setUserVisibleHint方法。
此时要对是否调用了onCreateView()方法进行标记判断。
*/
|
三、其它切换
1. Activity 切换到 Fragment 的生命周期变化
- Fragment 的生命周期变化为:onStart()、onResume()
2. 从 Fragment 1 进行锁屏操作
- Fragment 的生命周期方法:onPause()、onSaveInstanceState()、onStop()。
3. 从解锁 到 Fragment 1 的生命周期
简单实现ImageView宽度填满屏幕,高度自适应的两种方式
两种方式
1.重写View的onMeasure方法
核心代码
1
2
3
4
5
6
7
8
9
10
11
12
|
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
Drawable d = getDrawable();
if(d!=null){
// ceil not round - avoid thin vertical gaps along the left/right
edgesintwidth = MeasureSpec.getSize(widthMeasureSpec);
//高度根据使得图片的宽度充满屏幕计算而得
intheight = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
setMeasuredDimension(width, height);
}else{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
|
2.设置ImageView的属性:
1
2
3
4
5
6
|
//宽度填满屏幕
android:layout_width=”match_parent”
android:scaleType=”fitXY”
android:layout_height=”wrap_content”
//保持比例,一定要设置
android:adjustViewBounds=”true”
|
Android使用Bundle+Message+Hundle进行线程间通信
数据是java自带数据对象(常规八种数据结构)
接收线程
1
2
3
4
5
6
7
8
9
10
11
|
public Handler mHandler=new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case CANSHU : String str1 = msg.getData().getString("text1");//接受msg传递过来的参数
String str2 = msg.getData().getString("text2");//接受msg传递过来的参数
initFinishMainActivity(str1, str2);
break;
default : break;
}
}
};
|
发送线程
1
2
3
4
5
6
7
|
Message msg = new Message();
msg.what = MainActivity.CANSHU;
Bundle bundle = new Bundle();
bundle.putString("text1","大明的消息传递参数的例子!"); //往Bundle中存放数据
bundle.putString("text2","Time:2011-09-05"); //往Bundle中put数据
msg.setData(bundle);//mes利用Bundle传递数据
activity.mHandler.sendMessage(msg);//用activity中的handler发送消息
|
数据是自定义对象时
自定义类
首先需要自定对象实现Serializable可序列化的接口,如下
1
2
3
4
5
6
7
8
9
10
11
|
public class Persion implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
|
接收线程
getString等改为
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public Handler mHandler=new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case CANSHU :
Persion persion=(Persion)(msg.getData().getSerializable("persion"));
//接受msg传递过来的参数
initFinishMainActivity(persion);
break;
default:
break;
}
}
};
|
发送线程
putString等改为putSerializable
1
2
3
4
5
6
7
8
9
10
|
Message msg = new Message();
msg.what = MainActivity.CANSHU;
Persion persion=new Persion();
String Name="zhangsan";
persion.setName(Name);
Bundle bundle = new Bundle();
bundle.putSerializable("persion",persion);
//往Bundle中存放数据
msg.setData(bundle);//mes利用Bundle传递数据
activity.mHandler.sendMessage(msg);//用activity中的handler发送消息
|
Android历史版本平台、SDK、版本名称对照(争取持续更新)
平台版本 |
SDK版本 |
版本名称 |
12.0 |
31 |
Android 12(Snow Cone)(刨冰) |
11.0 |
30 |
Red Velvet Cake(Quince Tart)(Android R)(11)(红丝绒蛋糕) |
10.0 |
29 |
(Android Q)(10) |
9.0 |
28 |
Pie (Android P)(派/馅饼) |
8.1 |
27 |
Oreo(Android O)(奥利奥) |
8.0 |
26 |
[Oreo(Android O)(奥利奥) |
7.1 |
25 |
Nougat(Android N)(牛轧糖) |
7.0 |
24 |
Nougat(Android N)(牛轧糖) |
6.0 |
23 |
Marshmallow(Android M)(棉花糖) |
5.1 |
22 |
Lollipop(Android L)(棒棒糖) |
5.0 |
21 |
Lollipop(Android L)(棒棒糖) |
4.4W |
20 |
KITKAT Wear(奇巧巧克力) |
4.4 |
19 |
[KITKAT(奇巧巧克力) |
4.3 |
18 |
JELLY_BEAN_MR2(软心豆粒糖/果冻豆) |
4.2 / 4.2.2 |
17 |
JELLY_BEAN_MR1(软心豆粒糖) |
4.1 / 4.1.1 |
16 |
JELLY_BEAN(软心豆粒糖) |
4.0.3 / 4.0.4 |
15 |
ICE_CREAM_SANDWICH_MR1(冰淇淋三明治) |
4.0 / 4.01 / 4.02 |
14 |
ICE_CREAM_SANDWICH(冰淇淋三明治) |
3.2 |
13 |
HONEYCOMB_MR2(蜂巢) |
3.1.X |
12 |
HONEYCOMB_MR1(蜂巢) |
3.0.X |
11 |
HONEYCOMB(蜂巢) |
2.3.3 / 2.3.4 |
10 |
GINGERBREAD_MR1(姜饼) |
2.3 |
9 |
GINGERBREAD(姜饼) |
2.2 / 2.2.1 |
8 |
Froyo(冻酸奶) |
2.1 |
7 |
Eclair_MR2(闪电泡芙) |
2.0.1 |
6 |
Eclair_MR1(闪电泡芙) |
2.0 |
5 |
Eclair(闪电泡芙) |
1.6 |
4 |
Donut(甜甜圈) |
1.5 |
3 |
Cupcake(纸杯蛋糕) |
1.1 |
2 |
Petit Four |
1.0 |
1 |
Astro / Bender(1.0有两版) |
Android资源管理器注意事项
/data/user/0是/data/data目录的软连接或者是快捷方式
第一步:指定layout_width与layout_height
在xml文件中设置的ImageButton的宽和高为:
1
2
3
4
|
<?xml version="1.0" encoding="utf-8"?>
<ImageButton
android:layout_width="100dp"
android:layout_height="100dp"/>
|
第二步:设置属性android:scaleType
ImageView的属性android:scaleType,即 ImageView.setScaleType(ImageView.ScaleType)。android:scaleType是控制图片如何 resized/moved来匹对ImageView的size。ImageView.ScaleType /
android:scaleType值的意义区别:
ImageButton属性 |
ImageButton解释 |
CENTER /center |
按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示 |
CENTER_CROP / centerCrop |
按比例扩大图片的size居中显示,使得图片长 (宽)等于或大于View的长(宽) |
CENTER_INSIDE / centerInside |
将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽 |
FIT_CENTER / fitCenter |
把图片按比例扩大/缩小到View的宽度,居中显示 |
FIT_END / fitEnd |
把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置 |
FIT_START / fitStart |
把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置 |
FIT_XY / fitXY |
把图片 不按比例 扩大/缩小到View的大小显示 |
scaleType属性 |
scaleType说明 |
CENTER /center |
在视图中心显示图片,并且不缩放图片 |
CENTER_CROP / centerCrop |
按比例缩放图片,使得图片长 (宽)的大于等于视图的相应维度 |
CENTER_INSIDE / centerInside |
按比例缩放图片,使得图片长 (宽)的小于等于视图的相应维度 |
FIT_CENTER / fitCenter |
按比例缩放图片到视图的最小边,居中显示 |
FIT_END / fitEnd |
按比例缩放图片到视图的最小边,显示在视图的下部分位置 |
FIT_START / fitStart |
把图片按比例扩大/缩小到视图的最小边,显示在视图的上部分位置 |
FIT_XY / fitXY |
把图片不按比例缩放到视图的大小显示 |
MATRIX / matrix |
用矩阵来绘制 |
end