最近参考 今日头条算法 ,优化了项目的屏幕适配策略。下面是适配过程中的一些心得,部分内容来源于网络。
为江源等地区用户提供了全套网页设计制作服务,及江源网站建设行业解决方案。主营业务为成都做网站、网站设计、江源网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
举个例子:屏幕分辨率为:1920*1080,屏幕尺寸为5吋的话,那么dpi为440。
dp就是密度自适应的像素。1dp表示 在dpi为160的设备上的一颗像素
px与dp的换算公式px = dp * (dpi / 160),很显然,由于相同分辨率但不同屏幕大小的设备dpi是不同的,导致px和dp的基本不存在一个固定的换算关系,为了方便屏幕适配,Android设置了6个通用的密度,换算px与dp时采取通用密度计算,而非设备实际的密度。
以下为6种通用密度,以及其最小的分辨率
得到上面通用密度之后,我们换算dp与px多了一种简便方式。Android系统用mdpi(160dpi)作为基准,此时1px = 1dp,又有px = dp * (dpi / 160),所以我们可以很容易的得到以下换算:
sp在dp的基础上引入了scaleFactor变量,一般用于字号,可在系统设置里调大。
同一张图片放到以上4个分辨率类型的文件夹里,在页面上呈现的效果如下
实际呈现的算法为: 图片尺寸 * 系统density / 文件夹 density
因为图片尺寸、系统density都是固定的,因此图片最终尺寸表现为: 图片放的位置越"low",呈现的尺寸越大
比如 图片宽度200px,系统 density =3,则图片宽度
下面是详细的解释
我们知道,不管在布局文件中填写的是什么单位,它最后都会被系统转化为 px。系统的转换算法如下:
可以看到 px = dp*density 。
横向适配的最终目的:让100dp的宽度,在各个机型上,在屏幕上所占的 比例相同 。
其核心算法是px = dp* density。通过修改density这个变量,我们可以让px和画布标注的px值一致,达到适配的效果。
美工同学提供的画布宽度为 750px(iphone6) ,开发中,我们对这些px标注 除2 得到dp值进行使用。
那么density如何求出呢? 根据系统算法px = dp*density,反推 density =px/dp
拿横向适配画布, density对于不同分辨率的手机修改后如下:
375是我们拿UI画布横向分辨率750/2得出。
一、activity
1.一个activity就是一个类,继承activity;
2.需要复写onCreate()方法;
3.每一个activity都需要在AndroidMainfest.xml清单上进行配置;
4.为activity添加必要的控件。
二、布局
线性布局:LinearLayout
1.填满父空间:fill_parent、match_parent
2.文本多大空间就有多大:warp_content
3.文字对齐方式:gravity
4.占屏幕的比例:layout_weight="1" 水平方向,则width=0,垂直方向,则height=0
5.一行显示,空间不够会省略:singleLine="ture" false会换行
6.背景:background="#ffffff"
7.水平布局:orientation="horizontal"
垂直布局:orientation="vertivcal"
表格布局:TableLayout
1.内边距:padding
2.外边距:marginLeft\Start、Right\End、Top、Bottom
三、RelativeLayout相对布局
layout_above 将该控件的底部置于给定ID控件之上
layout_below 将该控件的顶部置于给定ID控件之下
layout_toLeftOf 将该控件的右边缘和给定ID控件的左边缘对齐
layout_toRightOf 将该控件的左边缘和给定ID控件的右边缘对齐
layout_alignBaseline 该控件的baseline和给定ID的控件的Baseline对齐
layout_alignBottom 该控件的底部边缘和给定ID的控件的底部边缘对齐
layout_alignLeft 该控件的左边缘和给定ID的控件的左边缘对齐
layout_alignRight 该控件的右边缘和给定ID的控件的右边缘对齐
layout_alignTop 该控件的顶部边缘和给定ID的控件的顶部边缘对齐
layout_alignparentBottom 如果该值为true,则该控件的底部和父控件的底部对齐layout_alignParentLeft 如果该值为true,则该控件的左边和父控件的左边对齐
layout_alignParentRight 如果该值为true,则该控件的右边和父控件的右边对齐
layout_alignParentTop 如果该值为true,则该控件的上边和父控件的上边对齐
layout_centerHorizontal 如果该值为true,则该控件将被置于水平方向的中央
layout_centerInParent 如果该值为true,则该控件将被置于父控件水平和垂直方向的中央
layout_centerVertival 如果该值为true,则该控件将被置于垂直方向的中央
四、一个Intent对象包含一组信息
1.Component name
2.Action
3.Data
4.Category
5.Extras
6.Flags
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent); //startActivity方法
intent.putExtra("Key", "Value"); //键值对
intent = getIntent();
String value = intent.getStringExtra("Key"); //通过键提取数据
五、初级控件:EditText、TextView、Button
1.获取EditText的值
String value = EditText.getText().toString();
2.将值放到Intent对象中
Intent intent = new Intent();
intent.putExtra("one",value )
intent.setCalss(Activity.this, OtherActivity.class);
3.使用这个Intent对象来启动Otheractivity
Activity.this.startActivity(intent);
4.将监听器的对象绑定到按钮对象上
button.setOnclickListener(new Listener());
5.得到Intent对象当中的值
Intent intent = getIntent();
String value1 = intent.getStringExtra("one");
int value2 = Integer.parseInt(value);
六、其他初级控件使用
①ImageView
②RadioGroup和RadioButton
setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener())
③Checkbox
setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener())
④Menu
1.当客户点击MENU按钮的时候,调用onCreateOptionMenu()方法
public boolean onCreateOptionMenu(Menu menu){
menu.add(0,1,1,R.string.id);
}
2.当客户点击MENU内部的具体某一个选项时,调用onOptionItemSelected()方法
public boolean onOptionItemSelected(MenuItem item){
if(item.getItemId() == 1){
finish();
}
return super.onOptionItemSelected(item);
}
七、Activity的生命周期
1.第一次创建时调用
protected void onCreat(Bundle saveInstanceState);
2.显示出来时调用
protected void onStrat();
3.获得用户焦点时调用(可操作)
protected void onResume();
4.点击弹出第二个Activity时调用
protected void onPause();
5.当第一个Activity不可见时调用
protected void onStop();
6.当返回第一个Activity时调用,代替OnCreate,因为没被销毁
protected void onRestart();
7.当返回第一个Activity时调用(先执行onStop,在执行,因为第二个Activity被销毁,不能返回获取,只能通过onCreat,onStart,onResume再创建)
protected void onDestory();
八、Task
1.Task是存放Activity的Stack栈。当点击启动第二个Activiry时,第一个Activtiy会被压入Stack栈当中,第二个Activity会位于栈的顶部;当返回第一个Activtiy时,第二个Activity会被弹出Stack,第一个Activity会位于栈的顶部,以此类推。
注释:当调用finish()时,当前的Activity会被Destory掉,栈中的Activity会消失。
2.当Activity都从Stack退出后,则就不存在Task。
九、高级控件
①进度条ProgressBar
水平进度条style="?android:attr/progressBarStyleHorizontal"
圆圈进度条style="?android:attr/progressBarStyle"
用户可视的visibility="gone"
②列表ListView
十、其他控件
A.下拉菜单Spinner
1.创建一个ArrayAdapter:
ArrayAdapterCharSequence adapter = ArrayAdapter.createFromResource(
this, //指上下文对象
R.array.plant_array, //引用了在文件中定义的String数组
android.R.layout.simple_spinner_item);//用来指定Spinner的样式,可替换自定义
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);//设置Spinner当中每个条目的样式
2.得到Spinner对象,并设置数据:
spinner=(spinner)findViewById(R.id.spinnerId);
spinner.setAdapter(adapter);
spinner.setPrompt("测试");//标题
3.创建监听器
class SpinnerOnSelectListener implements OnItemSelectedListener{
@override
public void onItemSelected(
AdapterView? adapterView,//整个列表对象
View view,//被选中的具体条目对象
int position,//位置
long id){ //id
String selected = adapterView.getItemAtPosition(position).toString();
}
@override
public void onNothingSelected(AdapterView? adapterView){
S.o.p("nothingSelected");
}
}
4.绑定监听器
spinner.setOnItemSelectedListener(new SpinnerOnSelectListener());
注:第二种动态设计
1.创建ArrayList对象
ListString list = new ArrayListString();
list.add("test1");
2. 调用方法
ArrayAdapter adapter = new ArrayAdapter(
this, //指上下文对象
R.layout.item, //引用了指定了下拉菜单的自定义布局文件
R.id.textViewId,//id
list);//数据
3.得到Spinner对象,并设置对象
spinner.setAdapter(adapter);
spinner.setPrompt("测试");//标题
3.创建监听器
class SpinnerOnSelectListener implements OnItemSelectedListener{
@override
public void onItemSelected(
AdapterView? adapterView,//整个列表对象
View view,//被选中的具体条目对象
int position,//位置
long id){ //id
String selected = adapterView.getItemAtPosition(position).toString();
}
@override
public void onNothingSelected(AdapterView? adapterView){
S.o.p("nothingSelected");
}
}
4.绑定监听器
spinner.setOnItemSelectedListener(new SpinnerOnSelectListener());
B.DatePicker和DatePickerDialog
1.声明一个监听器,使用匿名内部类
DatePickerDialog.OnDateSetListener onDateSetListener
= new DatePivkerDialog.OnDateSetListener(){
public void onDateSet(
DatePicker view,
int year,
int monthOfYear,
int dayOfMonth){
S.o.p(year+"-"+motnOfYear+"-"+dayOfMonth)
}
}
2.复写onCreateDialog(int id)方法:
@override
protected Dialog onCreateDialog(int id){
switch(id){
case DATE_PICKER_ID:
return new DatePickerDialog(this,onDateSetListener,2019,11,25);
}
return null;
}
3.使用时调用showDialog()方法
showDialog(DATE_PICKER_ID);
C.AutoCompleteTextView
B.Widget
C.Animatin
十一、实现ContentProvider过程
1.定义一个CONTENT_URI常量
2.定义一个类,继承ContentProvider
3.实现query、insert、update、delete、getType和onCreate方法
4.在AndroidManifest.xml当中进行声明
Android开发简单来说,就是在安卓系统的手机上制作APP,现在安卓手机市场份额大,对人才的需求也是很高的
Android开发,需要掌握以下知识:
android以java为基础的,所以前提要学好Java基础知识,比如基本类型、集合等。
android api,学习基本的Activity、service、intent等基本的知识,可以开发一些界面。
计算机网络基本知识。
Linux命令、C编程基础、Android Java编程、Google Android Linux操作系统具体操作等
课 工 场的Android开发教学系统非常完备,如果有这方面的学习需求,可以点 击 头 像试听课程了解一下。
安卓开发要学多久,安卓开发如果自学的话,没有系统性的学习,而且缺乏项目经验的实践是难以真正掌握的。
培训机构对于安卓开发的培训,一般有4个月到半年的不等。
安卓开发要学多久,学习android又需要哪些技能基础呢。
1、Java基础知识很多朋友一上手就开始学习Android,似乎太着急了一些。
Android应用程序开发是以Java语言为基础的,所以没有扎实的Java基础知识,只是机械的照抄别人的代码,是没有任何意义的。
万丈高楼平地而起,Java就是筑起高楼的每一块砖头。
那么Java学到什么程度才算是过关呢?我个人认为至少要掌握以下两个方面的内容:a)Java基础语法:具体的知识点列表可以在这里下载:《Java知识点列表》V1.0。
这部分内容没有讨价还价的余地,必须烂熟于胸。
至于具体的学习方法,可以看书或者是看视频,但是关键是要多加练习,无论是书上的练习还是视频里面的练习,都需要仔仔细细的完成;b)设计模式:由于在Android系统的框架层当中,使用了大量的设计模式,如果没有这个方面的知识,对于Android的理解就会大打折扣。
设计模式的种类非常之多,一个一个的全部掌握,是不现实的,必须首先掌握面向对象的基础设计原则,有了这些基础原则的支持,就可以举一反三。
这部分内容可以在《EffectiveJava》和《Agile.Software.Development:Principles,Patterns.and.Practices》这两本书中找到。
2、Linux基础知识大家都知道,Android系统的基础是Linux操作系统。
在开发过程当中,我们也需要使用到一些Linux命令。
所以说一些Linux的基础知识是必须的(话说现在的程序员,不懂Linux都不好意思跟人家打招呼),广州北大青鸟推荐大家看看北大青鸟相当不错;3、数据库基础知识这个比较简单,就是一个增删改查的数据库操作,可以看一下这本书:《SQL编程练习与解答》。
4、网络协议至少需要学习两种基础的协议,HTTP协议与Socket协议;5、Android基础知识此知识点的篇幅较大,在这里就不作更多解释了。
android以java为基础的,所以前提要学好Java基础知识,比如基本类型、集合等。
android api,学习基本的Activity、service、intent等基本的知识,可以开发一些界面。
计算机网络基本知识。
Linux命令、C编程基础、Android Java编程、Google Android Linux操作系统具体操作等
安卓系统开发的方法,简单来说分成四层:
第一层,以Inventor为代表的绘图工具,是Google推出的简单开发工具,主要是针对初级玩家的玩意儿,操作起来确实容易,一个不懂程序开发的用户就可以通过拖拽搞出一个能在安卓平台上跑的应用来,有点像做PPT,但任何事情都有两面性,这种容易上手的绘图工具,无法实现业务逻辑,运行效率也比较低。
第二层,以Rexsee为代表的无线中间件,这种方法就不是玩家用的了,必须是工程师来用,但对技术门槛的要求很低,会用HTML和JS的技术员就可以方便的使用,在技术要求大幅度降低的同时,基础功能的封装也是一大亮点,这些中间件已经把所有应用需要的基础功能封装好,程序员直接使用JS去调用就可以了,不再需要吭哧吭哧从零开始写代码,比如你想调用个GPS,本来要编几千行的代码,用中间件只需一行JS代码即可搞定,难怪说做中间件的厂商都说:“用了我的东西,你的程序已经做了一大半啦!”此言不虚。
第三层,基于JAVA的JDK JDK(Java Development Kit),目前绝大部分应用都是用这种方式来开发,对程序员的要求比较高,首先要有比较好的JAVA底子,然后要对Android平台本身有很深的研究,门槛不算低。