Android开发——Fragment、菜单、自定义控件

开启事务一.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.自定义组合控件

主要:通过View.inflate(context,子控件,父控件)的方式为作为父控件的ViewGroup添加子控件,等同于父控件通过addView(子控件)

1.1 自定义控件属性

了解:可以去【sdk\platforms\android-11\data\res\values\attrs】中查看系统是如何定义Android中自带控件属性的

(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.加强已有控件

注:这是自定义控件的一种,要修改已有控件的某功能或者加强功能时用到。例如:设置TextView的获取焦点、取消ViewPager的预加载和滑动功能

3.自定义控件

特点:自定义类,继承View或者ViewGroup,ViewGroup可以有自己的孩子,View不能有

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:alphasetAlpha(float)设置该组件的透明度
android:backgroundsetBackgroundResoucrce(int)设置该组件的背景颜色
android:clickablesetClickable(boolean)设置该组件是否可以激发点击事件
android:contentDescriptionsetContentDescription(CharSequence)设置该组件的内容描述信息
android:drawingCacheQualitysetDrawingCacheQuality(int)设置该组件所使用的绘制缓存的质量(可控制内存的消耗)
android:elevationsetElevation(float)设置该组件浮起来的高度,通过该属性可让组件呈现3D效果
android:fadeScrollbarssetScrollbarFadingEnabled(boolean)当不使用该组件的滚动条时,是否淡出显示滚动条
android:fadingEdgesetVerticalFadingEdgeEnable(boolean)设置滚动组件时组件边界是否使用渐变淡出效果(值有none、Vertical、Horizontal)
android:fadingEdgeLengthsetVerticalFadingEdgeLength(int)设置渐变淡出边界的长度
android:focusablesetFocusable(boolean)设置该组件是否可以得到焦点
android:focusableInTouchModesetFocusableTouchMode(boolean)设置该组件在触摸模式下是否可以得到焦点
android:idsetId(int)设置该组件的唯一标识
android:isScrollContainersetScrollContainer(boolean)设置该组件是否可作为滚动的容器使用
android:keepScreenOnsetKeepScreenOn(boolean)设置该组件是否会强制手机屏幕一直打卡(手机不会锁屏,屏幕会常亮)
android:longClickablesetLoneClickable(boolean)设置该组件是否可以响应长单机事件
android:miniHeightsetMinimumHeight(int)设置该组件的最小高度
android:miniWidthsetMinimubWidth(int)设置该组件的最小宽度
android:nextFocusDownsetNextFoucsDownId(int)设置焦点在该组件上,且单机向下键时获得焦点的组件ID
android:nextFocusLeftsetNextFocusLeftId(int)设置焦点在该组件上,且单机向左建时获得焦点的组件ID
android:nextFocusRightsetNextFoucsRightId(int)设置焦点在该组件上,且单机向右键时获得焦点的组件ID
android:nextFoucsUpsetNextFocusUpId(int)设置焦点在该组件上,且单机向上键时获得焦点的组件ID
android:onClick 为该组件的单机事件绑定监听器
android:paddingsetPadding(int,int,int,int)在组件的四边设置填充区域,内边距
android:rotationsetRotation(float)设置该组件旋转的角度
android:rotationXsetRotationX(float)设置该组件绕X轴旋转的角度
android:rotationYsetRotationY(float)设置该组件绕Y轴旋转的角度
android:saveEnablesetSaveEnable(boolean)如果设置为false,那么当该组件被冻结时不会保存他的状态(旋转屏幕是冻结状态)
android:scaleXsetScaleX(float)设置该组件水平方向的缩放比
android:scaleYsetScaleY(float)设置该组件垂直方向的缩放比
android:scrollbarAlwaysDrawHorizontalTrack 设置该组件是否总是显示水平滚动条的轨道
android:scrollbarAlwaysDrawVerticalTrack 设置该组件是否总是显示垂直滚动条的轨道
android:scrollbarDefaultDelayBeforeFadesetScrollBarDefaultDelayBeforeFade(int)设置滚动条在渐变淡出隐藏之前延迟多少秒
android:scrollbarFadeDurationsetScrollBarFadeDuration(int)设置滚动条弹出隐藏过程需要多少秒
android:scrollbarSizesetScrollBarSize(int)设置垂直滚动条的宽度和水平滚动条的高度
android:scrollbarStylesetScrollBarStyle(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:soundEffectsEnablesetSoundEffectsEnable(boolean)设置该组件被单击时是否使用音效
android:tag 为该组件设置一个字符串类型的tag值。可以通过view.getTag()获取到字符串。也可以通过view.findViewWithTag()来查询到该组件
android:transformPivotXsetPivotX(float)设置该组件旋转时旋转中心的X坐标
android:transformPivotYsetPirvotY(float)设置该组件旋转时旋转中心的Y坐标
android:translationXsetTranslationX(float)设置该组件在X方向上的位移
android:translationYsetTranslationY(float)设置该组件在Y方向上的位移
android:translationZsetTranslationZ(float)设置在组件在Z方向上的位移
android:visiblitysetVisbility(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——对中文一句话进行分词处理,获取关键词,之后我们就可以进行关键词匹配的操作


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值