开启事务一.Fragment
注明:就是Activity的一个模块,可以多个Fragment在一个Activity之中,Fragent必须嵌入到一个Activity之中
注意:由于这是API 11 出现的新特性,所以工程的最小支持版本要至少调制到11
1.创建Fragment的两种方法
1.1 静态创建
解释:这是包含两个Fragment的Activity布局文件,分别定义好两个Fragment类ArticleListFragment、ArticleReaderFragment,这两个类要继承Fragment,然后分别让每个类加载自己的Fragment布局文件即可
标注:这种方法在实际开发中基本不会用到,一般使用动态添加Fragment的方法
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Activity中的两个子Fragment -->
<fragment android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.news.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
1.2 动态注册
FragmentManager fragmentManager = getFragmentManager(); //获取Fragment的管理者
FragmentTransaction transaction = fragmentManager.beginTransaction(); //通过Fragment管理者开启事务
transaction.replace(android.R.id.content, new Fragmeng1()); //android.R.id.content——代表手机当前的窗体,系统定义好的id值。把当前窗体中的内容替换为指定Fragment,这是事务的替换方法
transaction.commit();//提交事务,才会对元数据进行修改
2.Fragment向下兼容
(1).为了让Fragment在3.0以下也支持,这时我们使用android.support.v4.app.Fragment时要使用v4包中的,不能使用普通的android.io.view下的
(2).让使用Fragment的Activity继承FragmentActivity类
(3).通过该类的getSupportFragmentManager()获取v4包中FragmentManager管理者
(4).剩下步骤与之前替换方法相同
3.Fragment使用涉及的API
3.1 Fragment类
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
onAttach(
Activity activity)
当Fragment依附在Activity时调用
| ||||||||||
void |
onCreate(
Bundle savedInstanceState)
当Fragment第一次创建时被调用
| ||||||||||
View |
onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
当第一次画fragment界面时调用这个方法。一般都在这个方法中写Fragment显示的逻辑
| ||||||||||
void |
onActivityCreated(
Bundle savedInstanceState)
当onCreateView返回的View完全初始化时被调用
| ||||||||||
void |
onStart()
当界面可见时被调用
| ||||||||||
void |
onResume()
当界面可交互时被调用,按钮可以被点击了
| ||||||||||
void |
onPause()
当界面不可交互时被调用,按钮不可被点击了
| ||||||||||
void |
onStop()
当界面不可见时被调用
| ||||||||||
void |
onDestroyView()
当onCreateView返回的View被销毁时调用
| ||||||||||
void |
onDestroy()
当Fragment被销毁时调用
| ||||||||||
void |
onDetach()
当Fragment失去附着的Activity时被调用
| ||||||||||
final Activity |
getActivity()
获取Fragment依附的Activity对象
|
3.2 FragmentManager抽象类
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract FragmentTransaction |
beginTransaction()
开启事务,
Fragment替换控件内容必须在事务中进行
| ||||||||||
abstract Fragment |
findFragmentByTag(
String tag)
可以获取指定Tag的Fragment对象,不过需要把这个Fragment强转为自定义的Fragment子类才可以调用自定义其他Fragment的方法
|
3.3 FragmentTransaction抽象类
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract FragmentTransaction |
replace(int containerViewId,
Fragment fragment,
String tag)
替换指定控件的内容为fragment,并且为这个fragment设置一个标记,这个标记可以为每一个Fragment创建自己的标识,你可以通过这个标识获取Fragment对象
| ||||||||||
abstract FragmentTransaction |
replace(int containerViewId,
Fragment fragment)
替换指定控件的内容为fragment
| ||||||||||
abstract int |
commit()
提交事务
|
3.4 Activity类
FragmentManager |
getFragmentManager()
获取Fragment管理者
|
3.5 FragmentActivity类
注明:为解决Fragment兼容性而写的Activity类
FragmentManager |
getSupportFragmentManager()
获取能解决兼容性问题的FragmentManager对象
|
二.菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// 类似布局填充器,可以吧res/menu文件转换为view
getMenuInflater().inflate(R.menu.main, menu);
/**
* groupId 分组
* itemId 通过该选项找到该Item
* order 是否排序
* 标题
*
*/
menu.add(0, 1, 0, "傲娇");
menu.add(0, 2, 0, "敖冷");
menu.add(0, 3, 0, "病娇");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings1:
Toast.makeText(this, "我是菜单1", Toast.LENGTH_SHORT).show();
break;
case R.id.action_settings2:
Toast.makeText(this, "我是菜单2", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(this, "我是菜单3", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(this, "我是菜单4", Toast.LENGTH_SHORT).show();
break;
case 3:
Toast.makeText(this, "我是菜单5", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
三.自定义控件相关
1.自定义组合控件
1.1 自定义控件属性
(1)values目录下创建一个【attrs.xml】文件
<resources>
<declare-styleable name="名称可以随意起,不过最好是自定义控件名"><!-- 固定标签 -->
<attr name="title" format="string"/><!-- 设置了三个属性,格式类型值有:string、boolean、refrence、float -->
<attr name="content_true" format="string"/>
<attr name="content_false" format="string"/>
</declare-styleable>
</resources>
(2)然后再自定义控件的布局文件中跟布局节点中,创建一个属于我们的命名空间
<LinearLayout
xmlns:heima="http://schemas.android.com/apk/res/com.heima.mobilesafe55"><!-- heima:就是命名空间名称,并且名称空间值书写格式后边必须是自己工程的包名,不能随意起 -->
</LinearLayout>
(3)引用格式如下
<com.heima.mobilesafe55.view.TextViewGroup
heima:content_false="自动更新已经关闭"
heima:content_true="自动更新已经开启"
heima:title="自动更新设置" /><!-- 用自定义的名称空间heima引用自定义的属性 -->
1.2 AttributeSet接口
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract int |
getAttributeCount()
获取该控件所有属性的个数
| ||||||||||
abstract String |
getAttributeName(int index)
通过属性的索引值获取属性名
| ||||||||||
abstract String |
getAttributeValue(int index)
通过属性的索引值获取属性值
| ||||||||||
abstract String |
getAttributeValue(
String namespace,
String name)
通过名称空间和控件名获取属性值,名称空间就是我们在布局文件中定义的超长字符串
|
2.加强已有控件
3.自定义控件
3.1 View类
注意:
(1)任何一个界面在绘制的过程中肯定会走这三个流程,onMeasure(测量布局大小)、onLayout(排版)、onDraw(绘制布局)
(2)注意控件获取值、设置值的所有方法如果在控件未绘制时,将不会起任何作用,获取的值为0,设置的值不会生效。不能再onCreat(),onStart()中调用相关方法
(3)onDraw()方法绘制时如果绘制的控件一部分超出屏幕,这样会自动减半的绘制这个控件,解决方法让控件不能滑出屏幕
测量三个方法总结:
(1)一般自定义view都需要自己设置自定义画布的高和宽,通过setMeasuredDimension()方法。不需要知道控件的宽和高,不用测量,这只是创建了画布,等待onDraw中随意的话而已
(2)一般自定义view都需要自己设置自定义画布的高和宽,通过setMeasuredDimension()方法。不需要知道控件的宽和高,没有测量,这是创建了画布,等待onDraw中随意的话而已
(3)onMeasure()方法只是控件的生命周期方法
自己的总结:
(1)setMeasuredDimension()设置画布==>onDraw()画控件
(2)measure()测量控件==>onLayout()或者获取控件高和宽
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
View(
Context context)
通过上下文初始化View
| |||||||||||
View(
Context context,
AttributeSet attrs)
通过属性值和上下文初始化View
| |||||||||||
View(
Context context,
AttributeSet attrs, int defStyleAttr)
通过上下文,属性值和主题样式来初始化View
|
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
onMeasure(int widthMeasureSpec, int heightMeasureSpec)
protected,生命周期方法,当前控件需要测量时调用。参数1:就是Xml布局文件中设置的控件宽度;参数2:同参数1 | ||||||||||
final void |
setMeasuredDimension(int measuredWidth, int measuredHeight)
protected,设置画当前控件画布的宽和高,一般在onMeasure()方法中调用 | ||||||||||
final void |
measure(int widthMeasureSpec, int heightMeasureSpec)
测量控件,哪个控件需要测量哪个控件调用 | ||||||||||
final int |
getMeasuredWidth()
获取控件测量后的宽度,必须先要测量
| ||||||||||
final int |
getMeasuredHeight()
获取控件测量后的高度,必须先要测量
| ||||||||||
void |
onLayout(boolean changed, int left, int top, int right, int bottom)
protected,对当前控件进行排版,ViewGroup中才需要.参数1-2:控件左上角点坐标值;参数3-4:控件右下角坐标值
| ||||||||||
void |
layout(int l, int t, int r, int b)
设置控件所在屏幕的位置。注意绘制界面的逻辑必须在Activity的onCreat()方法之后执行才会生效,必须在绘制控件完毕后你才能修改控件的布局位置
| ||||||||||
void |
onDraw(
Canvas canvas)
protected,画画板,不过画的内容在View上,直接调用参数的Convas对象画即可,画的内容全部显示在View上。这个View是已经测量好的画板
| ||||||||||
void |
invalidate()
刷新当前控件,将进行重绘的操作,onDraw()方便将被再次调用。必须是UI线程
| ||||||||||
void |
postInvalidate()
刷新当前控件,将进行重绘的操作,onDraw()方便将被再次调用。不是UI线程需要用此方法刷新控件 | ||||||||||
boolean |
onTouchEvent(
MotionEvent event)
设置自己的触摸监听,返回值表示是否让当前控件消费掉事件
问题:onTouchEvent()和setOnTouchListener()使用方法区别?
解答:能够设置触摸监听的控件中的onTouchEvent()中的实现逻辑是这样的,它调用了回调接口中方法,从而调用了触摸监听中的具体逻辑
| ||||||||||
void |
scrollBy(int x, int y)
移动的位移,参数表示移动的位移值。注意:移动的是window窗口
| ||||||||||
void |
scrollTo(int x, int y)
移动到具体位置,参数表示移动到的坐标点。注意:移动的是window窗口
| ||||||||||
final int |
getScrollX()
获取window在x轴移动的位移值
| ||||||||||
final int |
getScrollY()
获取window在y轴移动的位移值
| ||||||||||
void |
computeScroll()
设置了Scroller一般需要设置此方法,此方法在刷新控件后就会被自动调用,我们一般要在该方法方法体中进行刷新操作,递归调用此方法,直到Scroller模拟的数据全部取完
| ||||||||||
final int |
getLeft()
获取控件左边距离窗口的距离
| ||||||||||
final int |
getTop()
获取控件上边距离窗口的距离
| ||||||||||
final int |
getRight()
获取控件上边距离窗口的距离
| ||||||||||
final int |
getBottom()
获取控件底边距离窗口的距离
| ||||||||||
final int |
getHeight()
获取控件的高度
| ||||||||||
final int |
getWidth()
获取控件的宽度
| ||||||||||
ViewGroup.LayoutParams |
getLayoutParams()
获取控件父布局的布局参数对象,通过这个布局参数对象可以设置控件的位置。这个布局参数设置的各种属性值就是Xml文件控件的各种参数
| ||||||||||
void |
setLayoutParams(
ViewGroup.LayoutParams params)
设置这个控件添加的哪个布局中的布局参数,自定义组合控件常用
| ||||||||||
void |
setPadding(int left, int top, int right, int bottom)
设置控件的内边距,设置为负值将移动到屏幕外边
| ||||||||||
void |
setEnabled(boolean enabled)
设置控件是否可点击
| ||||||||||
final ViewParent |
getParent()
获取该控件的父控件
| ||||||||||
void |
getLocationInWindow(int[] location)
获取控件在窗口中位置,存放到一个int[]数组中 | ||||||||||
void |
getLocationOnScreen(int[] location)
获取控件在屏幕中位置,存放到一个int[]数组中 |
3.1.1 Scroller类
注:一般要与View中的computeScroll()方法连用
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
startScroll(int startX, int startY, int dx, int dy, int duration)
模拟移动。参数1:x轴模拟开始的位置;参数2:y轴模拟开始的位置;参数3:x轴模拟数据的个数;参数4:y轴模拟数据的个数;参数5:运动的时长,可以根据模拟的个数得出时间值
| ||||||||||
boolean |
computeScrollOffset()
模拟移动的所有数值个数是否被取完
| ||||||||||
final int |
getCurrX()
获取模拟移动变换的x值
| ||||||||||
final int |
getCurrY()
获取模拟移动变换的x值
|
XML属性 | 相关方法 | 说明 |
android:alpha | setAlpha(float) | 设置该组件的透明度 |
android:background | setBackgroundResoucrce(int) | 设置该组件的背景颜色 |
android:clickable | setClickable(boolean) | 设置该组件是否可以激发点击事件 |
android:contentDescription | setContentDescription(CharSequence) | 设置该组件的内容描述信息 |
android:drawingCacheQuality | setDrawingCacheQuality(int) | 设置该组件所使用的绘制缓存的质量(可控制内存的消耗) |
android:elevation | setElevation(float) | 设置该组件浮起来的高度,通过该属性可让组件呈现3D效果 |
android:fadeScrollbars | setScrollbarFadingEnabled(boolean) | 当不使用该组件的滚动条时,是否淡出显示滚动条 |
android:fadingEdge | setVerticalFadingEdgeEnable(boolean) | 设置滚动组件时组件边界是否使用渐变淡出效果(值有none、Vertical、Horizontal) |
android:fadingEdgeLength | setVerticalFadingEdgeLength(int) | 设置渐变淡出边界的长度 |
android:focusable | setFocusable(boolean) | 设置该组件是否可以得到焦点 |
android:focusableInTouchMode | setFocusableTouchMode(boolean) | 设置该组件在触摸模式下是否可以得到焦点 |
android:id | setId(int) | 设置该组件的唯一标识 |
android:isScrollContainer | setScrollContainer(boolean) | 设置该组件是否可作为滚动的容器使用 |
android:keepScreenOn | setKeepScreenOn(boolean) | 设置该组件是否会强制手机屏幕一直打卡(手机不会锁屏,屏幕会常亮) |
android:longClickable | setLoneClickable(boolean) | 设置该组件是否可以响应长单机事件 |
android:miniHeight | setMinimumHeight(int) | 设置该组件的最小高度 |
android:miniWidth | setMinimubWidth(int) | 设置该组件的最小宽度 |
android:nextFocusDown | setNextFoucsDownId(int) | 设置焦点在该组件上,且单机向下键时获得焦点的组件ID |
android:nextFocusLeft | setNextFocusLeftId(int) | 设置焦点在该组件上,且单机向左建时获得焦点的组件ID |
android:nextFocusRight | setNextFoucsRightId(int) | 设置焦点在该组件上,且单机向右键时获得焦点的组件ID |
android:nextFoucsUp | setNextFocusUpId(int) | 设置焦点在该组件上,且单机向上键时获得焦点的组件ID |
android:onClick | 为该组件的单机事件绑定监听器 | |
android:padding | setPadding(int,int,int,int) | 在组件的四边设置填充区域,内边距 |
android:rotation | setRotation(float) | 设置该组件旋转的角度 |
android:rotationX | setRotationX(float) | 设置该组件绕X轴旋转的角度 |
android:rotationY | setRotationY(float) | 设置该组件绕Y轴旋转的角度 |
android:saveEnable | setSaveEnable(boolean) | 如果设置为false,那么当该组件被冻结时不会保存他的状态(旋转屏幕是冻结状态) |
android:scaleX | setScaleX(float) | 设置该组件水平方向的缩放比 |
android:scaleY | setScaleY(float) | 设置该组件垂直方向的缩放比 |
android:scrollbarAlwaysDrawHorizontalTrack | 设置该组件是否总是显示水平滚动条的轨道 | |
android:scrollbarAlwaysDrawVerticalTrack | 设置该组件是否总是显示垂直滚动条的轨道 | |
android:scrollbarDefaultDelayBeforeFade | setScrollBarDefaultDelayBeforeFade(int) | 设置滚动条在渐变淡出隐藏之前延迟多少秒 |
android:scrollbarFadeDuration | setScrollBarFadeDuration(int) | 设置滚动条弹出隐藏过程需要多少秒 |
android:scrollbarSize | setScrollBarSize(int) | 设置垂直滚动条的宽度和水平滚动条的高度 |
android:scrollbarStyle | setScrollBarStyle(int) | 设置滚动条的风格和位置。属性值如下 insideOvarlay:默认值,表示在padding区域内并且覆盖在view上 insideInset:表示在padding区域内并插入在view后边 outsideOverlay:在padding区域外并且覆盖在view之上,推荐 outsideInset:表示在padding区域外并插入在view后边 |
android:scrollbarThumbHorizontal | 设置该组件的水平滚动条的滑块对应的Drawable对象 | |
android:scrollbarThumbVertical | 设置该组件的垂直滚动条的滑块对应的Drawable对象 | |
android:scrollbarTrackHorizontal | 设置该组件的水平滚动条的轨道对应的Drawable对象 | |
android:scroolbarTrackVertical | 设置该组件的垂直滚动条的轨道对应的Drawable对象 | |
android:scrollbars | 设置滑动过程中显示滚动条样式(none、Vertical、Horizontal) | |
android:soundEffectsEnable | setSoundEffectsEnable(boolean) | 设置该组件被单击时是否使用音效 |
android:tag | 为该组件设置一个字符串类型的tag值。可以通过view.getTag()获取到字符串。也可以通过view.findViewWithTag()来查询到该组件 | |
android:transformPivotX | setPivotX(float) | 设置该组件旋转时旋转中心的X坐标 |
android:transformPivotY | setPirvotY(float) | 设置该组件旋转时旋转中心的Y坐标 |
android:translationX | setTranslationX(float) | 设置该组件在X方向上的位移 |
android:translationY | setTranslationY(float) | 设置该组件在Y方向上的位移 |
android:translationZ | setTranslationZ(float) | 设置在组件在Z方向上的位移 |
android:visiblity | setVisbility(boolean) | 设置该组件是否可见 |
3.2 ViewGroup类
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
View |
getChildAt(int index)
获取指定索引位置的子控件
| ||||||||||
int |
getChildCount()
获取子控件的个数,对应孩子的索引值
| ||||||||||
boolean |
dispatchTouchEvent(
MotionEvent ev)
事件分发机制,重写了View中的dispatchTouchEvent,添加了传递的机制
| ||||||||||
boolean |
onInterceptTouchEvent(
MotionEvent ev)
事件拦截机制,是否拦截事件,拦截后将不再向下传递
| ||||||||||
void |
requestDisallowInterceptTouchEvent(boolean disallowIntercept)
请求这个控件不拦截事件,参数为true表示该控件onInterceptTouchEvent()方法返回false;反之返回true
|
4.事件传递机制
4.1 View
(1)可点击的view:onTouch()返回true和false全部事件都响应。dispatchTouchEvent返回的都是true
(2)不可点击的view:onTouch()返回false只有down事件被响应,dispatchTouchEvent返回的是false;返回true全部事件都响应,dispatchTouchEvent返回的是true
(3)onTouch()返回true,同控件的setOnClickListener()将不会被触发;返回false,才能够被触发。因为返回true不会走源码中的onTouchEvent()的逻辑
4.2 ViewGroup
(1)判断你点中的点是否落在ViewGroup矩形区域内,落在说明ViewGroup被点中
(2)递归判断你点下位置在落在哪个最子级控件中,这个过程即事件传递的过程
(3)传递过程中如果某一个ViewGroup的onInterceptTouchEvent返回false,事件不再向下传递,会被拦截掉
(4)传递到最子级控件,控件尝试去响应,dispatchTouchEvent返回true,事件传递将结束;dispatchTouchEvent返回false,事件将回传给其父控件
(5)注意回传过程中涉及到ViewGroup处理事件,其处理事件与View的dispatchTouchEvent的逻辑相同,因为源码中它调用的就是View的dispatchTouchEvent方法。所以ViewGroup是否响应事件仍然看OnTouchEvent()方法
4.3 ViewPager
(1)普通的点击和抬起事件传递就是ViewGroup的传递机制
(2)当你滑动到一定距离或者达到某种速度时,ViewPager的内部View会触发cancel事件,然后事件就不会向内部控件进行传递了
特:
1.分词框架:Lucene——对中文一句话进行分词处理,获取关键词,之后我们就可以进行关键词匹配的操作