欢迎光临散文网 会员登陆 & 注册

UI进阶

2021-07-06 09:31 作者:独行D暗灵  | 我要投稿

Fragment

  • Android从3.0开始引入Fragment(碎片)

  • 允许将Activity拆分成多个完全独立封装的可重用的组件

  • 每个组件拥有自己的生命周期和UI布局

  • 为不同型号、尺寸、分辨率的设备提供统一的UI设计方案


  • 自定义的Fragment必须继承Fragment类或其子类

创建Fragment

  • 通常在创建Fragment时,需要实现三个方法∶

    1. onCreate()

    2. onCreateView()

    3. onPause()

  • 将Fragment加载到Activity中主要有两种方式∶

    1. 把Fragment添加到Activity的布局文件中

    2. 在Activity的代码中动态添加Fragment


管理Fragment

  • 通过FragmentManager实现管理Fragment对象的管理

  • 通过getFragmentManager()获取FragmentManager对象

  • FragmentManager能够完成以下三方面的操作︰

    1. 通过findFragmentByld()或findFragmentByTag()方法,来获取Activity中已存在的Fragment对象

    2. 通过popBackStack()方法将Fragment从Activity的后退栈中弹出

    3. 通过addOnBackStackChangedListerner()方法来注册一个侦听器以监视后退栈的变化


  • 获取FragmentTransaction对象

 FragmentManager fragmentManager=getFragmentManager ( ) ;
 FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();


FragmentTransaction被称作Fragment事务,与数据库事务类似,Fragment事务代表了Activity对Fragment执行的多个改变操作。


  • 事务中动作的执行顺序可以随意,但需注意以下两点:

    • 程序的最后必须调用commit()方法

    • 程序中添加了多个Fragment对象,显示的顺序跟添加顺序一致

    • 当删除Fragment对象时,在没有调用addToBackStack()方法情况下,Fragment对象会被销毁

调用commit(O后,事务并不会马上提交,而是会在Activity的UI线程中等待直到线程能执行的时候才执行。


与Activity通讯

  • Fragment获取其所在的Activity中的组件

 View listview=getActivity ( ).findViewById(R.id.list);

  • Activity获取指定Frament实例

 ExampleFragment fragment = (ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment)
 

  • 在Fragment中定义回调接口

 public static class FragmentA extends ListFragment {
  //Activity必须实现下面的接口
  public interface OnNewsSelectedListener {
         //传递当前被选中的标题的id
   public void onNewsSelected ( long id) ;
     }
 }

  • Fragment与Activity共享事件

 public static class FragmentA extends ListFragment {
     OnNewsSelectedListener mListener;
     //.. ....省略
     @override
     public void onListItemClick(Listview l,View v,int position,long id){
         mListener.onNewsselected (id);
     }
  //......省略
 }

在数据传递时,也可以直接把数据从FragmentA传递给FragmentB,不过该方式降低了Fragment的可重用的能力。现在的处理方式只需要把发生的事件告诉宿主,由宿主决定如何处置,以便Fragment的重用性更好。


Fragment的生命周期

  • Fragment的生命周期具有以下四个状态:

    1. 活动状态

    2. 暂停状态

    3. 停止状态

    4. 销毁状态

  • Fragment生命周期中的方法

方法功能描述onAttach()当一个Fragment对象关联到一个Activity时被调用onCreate()初始化创建Fragment对象时被调用onCreateView()当Activity获得Fragment的布局时调用此方法onActivityCreated()当Activity对象完成自己的onCreate()方法时调用onStart()Fragment对象在UI界面可见时调用onResume()Fragment对象的UI可以与用户交互时调用onPause()由Activity对象转为onPause状态时调用onStop()有组件完全遮挡,或者宿主Activity对象转为onStop状态时调用onDestroyView()Fragment对象清理View资源时调用,即移除Fragment中的视图onDestroy()Fragment对象完成对象清理View资源时调用onetach()当Fragment被从Activity中删掉时被调用


  • Fragment和Activity两者之间生命周期的关系

    • Activity直接影响其所包含的Fragment的生命周期

    • Fragment的回调方法要比Activity多,多出的方法主要用于与Activity的交互

    • 当Activity进入运行状态时(即running状态) ,才允许添加或删除Fragment

    • 有当Activity处于resumed状态时,Fragment的生命周期才能独立运转

    • 其他阶段依赖于Activity的生命周期


静态方式

  • Fragment的生命周期调用过程:

    • onPause()

    • onStop()

    • onDestroyView()

    • onDestroy()

    • onDetach()

    • onStart()

    • onResume()

    • onPause()

    • onStop()

    • onAttach()

    • onCreate()

    • onCreateView()

    • onActivityCreated()

    • onStart()

    • onResume()

    • 当首次展示布局页面时,其生命周期方法调用的顺序是︰

    • 当关闭手机屏幕或者手机屏幕变暗时,其生命周期方法调用的顺序是︰

    • 当对手机屏幕解锁或者手机屏幕变亮时,其生命周期方法调用的顺序是︰

    • 当对Fragment所在屏幕按返回键时,其生命周期方法调用的顺序是︰


Menu菜单和ToolBar

Menu菜单

  • Android中提供的菜单有如下几种

    • 选项菜单

    • 子菜单

    • 上下文菜单

    • 图标菜单

    • 扩展菜单

Options Menu选项菜单

  • 系统创建菜单的方法主要有以下两种:

    • onCreateOptionsMenu():创建选项菜单

    • onCreateContextMenu():创建上下文菜单

  • 上下文菜单使用onCreateOptionsMenu()回调方法对菜单进行初始化;使用onPrepareOptionsMenu()方法动态改变选项菜单的内容


  • 创建并显示Menu菜单

 @override
 public boolean onCreateOptionsMenu (Menu menu) {
     super.onCreateOptionsMenu (menu) ;
     //添加4个菜单项,分成2组
     int group1 = 1;
     int gourp2 = 2;
     menu.add (group1, 1, 1,"菜单项1");
     menu.add (group1, 2,2,"菜单项2");
     menu.add (gourp2,3,3,"菜单项3");
     menu. add (gourp2, 4, 4,"菜单项4");
     //显示菜单
     return true;
 }
 


响应菜单项

  • Android为菜单提供了两种响应方式:

    • onOptionsItemSelected()方法

    • onMenuItemSelected()方法

  • onMenuItemSelected与onOptionsItemSelected区别:

    • onMenuItemSelected():当选择选项菜单或上下文菜单都会触发该事件处理方法

    • onOptionsItemSelected():该方法只在选项菜单被选中时才会被触发

如果Activity中同时重写onMenuItemSelected()和onOptionsItemSelected()方法时,当点同一个菜单项时,将先调用onMenuItemSelected()方法,然后调用onOptionsItemSelected()方法性。


  • onOptionsItemSelected()方法

 @override
 public boolean onOptionsItemSelected (MenuItem item){
     switch (item. getItemId () ){
         case 1:
             Toast.makeText(this,"菜单项1",Toast. LENGTH_SHORT) .show ();
             break;
         case 2: ...
  }
  return super.onOptionsItemSelected (item) ;
 }


  • onMenuItemSelected()方法

 @override
 public final boolean onMenuItemSelected (intfeatureId,MenuItem item){
     switch (item. getItemId()) {
         case 1:
             Toast.makeText(this,"菜单项11",Toast.LENGTH_SHORT).show ();
         case 2:
         case 3:
         case 4:
  }
  return super.onMenuItemSelected (featureId, item ) ;
 }


SubMenu子菜单

  • 创建步骤:

    1. 重写Activity类的onCreateOptionsMenu()方法

    2. 调用Menu的addSubMenu()方法添加子菜单

    3. 调用SubMenu的add()方法为子菜单添加菜单项

    4. 重写Activity类的onOptionsItemSelected()方法

当调用setIcon)方法设置图标时,图标无法显示是因为在MenuBuilder的optionalIconsVisible属性默认为false。当要显示图标时,需要通过反射机制调用MenuBuilder对象的setOptionalIconsVisible)方法,将其设置为true即可。


  • 创建子菜单

 public boolean onCreateOptionsMenu (Menu menu){
     //添加子菜单
     SubMenu subMenu = menu.addSubMenu ( 0,2,Menu .NONE,"基础操作");
     subMenu .setIcon (android.R.drawable.ic_menu_manage);setIconEnable (menu);
     //添加子菜单项
     //重命名菜单项
     MenuItem renameItem = subMenu . add(2,201,1,"重命名");
     renameItem.setIcon (android.R.drawable.ic_menu_edit);
     //......
 }
 


ContextMenu上下文菜单

  • 上下文菜单是通过调用ContextMenu接口中的方法来实现

  • onCreateContextMenu()方法来生成ContextMenu对象

 onCreatecontextMenu(contextMenu menu,viewv ,ContextMenu .ContextMenuInfo menuInfo)
 

当需要传递额外信息时,需要重写getContextMenuInfo(方法,并返回一个带有数据的ContextMenuInfo实现类对象。


使用XML资源生成菜单

  • 使用XML资源生成菜单项的步骤:

    1. 在res目录中创建menu子目录

    2. 在menu子目录中创建一个Menu Resource file ( XML文件)

    3. 使用XML文件的资源ID,在Activity中将XML文件中所定义的菜单元素添加到menu对象中

    4. 通过判断菜单项对应的资源ID来实现响应的事件处理

  • 使用XML资源生成菜单1

 <menu>
     <group android: id="@+id/ group1" >
         <item
               android: id="@+id/ item_send"
               android: title="发送"/>
         <item
               android:id="@+id/ item_rename"
               android: title="重命名"/>
         <item
               android: id="@+id/ item_del"
               android: title="删除"/>
     </group>
 </menu>
 

  • 使用XML资源生成菜单2

 contextMenuBtn = (Button)
 findViewById(R.id.contextMenuBtn) ;
 //为按钮注册上下文菜单,长按按钮则弹出上下文菜单
 this.registerForContextMenu(contextMenuBtn);
 @override
 public void onCreateContextMenu(ContextMenu menu,View v,ContextMenuInfo menuInfo){
     menu.setHeaderTitle ("文件操作");
     getMenuInflater().inflate(R.menu.context_menu,menu);
 }

  • 资源文件实现子菜单

 <item android :title="系统设置">
     <menu>
     <item android:id="@+id/mi_display_setting"
           android:title="显示设置"/>
     <item android:id="@+id/mi_network_setting"
           android:title="网络设置"/>
     <!--其他菜单项-->
 </menu>
 

  • 为菜单项添加图标

 <item
       android:id="@+id/mi_exit"
       android:title="退出"
       android : icon="@drawable/exit"/ >
 

  • 设置菜单项的可选策略

 <group android:id="... "
        android: checkableBehavior="all">
 <!--菜单项-->
 </group>
 

  • 使用android:checked设置特定菜单项

 <item
       android:id="..."
       android:title="sometitle"
       android:checked="true"/>
 

  • 为菜单项添加图标

 <item
       android:id=" ..."
       android:title="sometitle"
       android:enabled="false"/>
 

  • 设置菜单项可见/不可见

 <item
       android:id="..."
       android:title="sometitle"
       android:visible="false"/>
 


Toolbar操作栏

  • Material Design风格的导航组件

  • 取代Actionbar

  • 为开发者预留许多可定制修改的余地∶

    1. 支持添加一个或多个的自定义组件

    2. 设置App的Logo图标

    3. 支持设置标题和子标题

    4. 设置导航栏图标

    5. 支持Action Menu


方法功能描述setTitle(int resId)设置标题setSubtitle(int resId)设置子标题setTitleTextColor(int color)设置标题字体颜色setSubtitleTextColor(int color)设置子标题字体颜色setNavigationIcon(Drawable icon)设置导航栏的图标setLogo(Drawable darwable)设置Toolbar的Logo图标


高级组件

AdapterView与Adapter

  • AdapterView实现过程类似于MVC架构

  • AdapterView实现过程

    • 控制层:Adapter适配器承担了控制层的角色

    • 视图层:AdapterView用于将前端显示和后端数据分离

    • 模型层:数组、XML文件等形式的数据

  • AdapterView具有以下特征:

    • AdapterView继承了ViewGroup,其本质上是容器

    • AdapterView可以包括多个”列表项“,并将”列表项“以合适的形式显示出来

    • AdapterView所显示的”列表项“是由Adapter提供,通过AdapterVIew的setAdapter()方法来设置Adapter适配器。


  • AdapterView及其子类的继承关系

通常将ListView、GridView、Spinner和Gallery等AdapterView子类作为容器,然后使用Adapter为容器提供“列表项”,AdapterView负责采用合适的方式显示这些列表项。


  • Adapter的常用子接口:

    • ListAdapter接口

    • baseAdapter抽象类

    • SImpleCursorAdapter类

    • ArrayAdapter类

    • SimpleAdapter类

Adapter对象扮演着桥梁的角色,通过桥梁连接着AdapterView和所要显示的数据。Adapter提供了一个连通数据项的途径,将数据集呈现到View中。


ListView列表视图

  • ListView通常具有两个职责:

    • 将数据填充到布局,以列表的方式来显示数据

    • 处理用户的选择、点击等操作SimpleCursorAdapter

  • 通常创建ListView的两种方式:

    • 直接使用ListView进行创建

    • 使用Activity继承ListActivity,实现ListView对象的获取

XML属性功能描述android:divider设置列表的分隔条android:dividerHeight用来指定分割条的高度android:entries指定一个数组资源android:footerDividersEnabled各个footer之间绘制分割条android:headerDividersEnabled各个header之间绘制分割条


  • ListView从AbsListView中继承的属性

XML属性描述android:cacheColorHint用于设置该列表的背景始终以单一、固定的颜色绘制android:choiceMode为视图指定选择的行为adnroid:drawSelectorOnTop如果为true,选中的列表项将会显示在上面android:fastScrollEnabled用于设置是否允许使用快速滚动滑块android:listSelector设置选中项显示的可绘制对象android:scrollingCache设置在滚动时是否使用绘制缓存,默认为true。android:smoothScrollbar列表会使用更精确的基于条目在屏幕上的可见像素高度的计算方法android:stackFromBottom设置是否将列表项从底部开始显示android:textFilterEnabled设置是否对列表项进行过滤android:transcriptMode设置该组件的滚动模式

  • 使用ListView步骤:

    • 准备ListView所要显示的数据

    • 使用数组或List集合存储数据

    • 创建适配器,作为列表项数据源

    • 将适配器对象添加到ListView,并进行展示


实现ListView

  • ListView组件本身默认的id为@id/android:list

  • 直接调用getListView()

  • 在ListActivity中显示其他组件的步骤∶

    • 先定义Activity的布局文件,在布局UI界面时先增加其他组件,再添加一个ListView组件用于展示数据

    • 在Activity中通过setContentView()方法来添加布局对象


  • 获取并绑定Activity中的ListView

 <!-— 默认的Listview -->
 <Listview
           android: id="@+id/ listview"
           android: layout_width="match_ parent"
           android: layout_height="0dip"
           android: layout_weight="1"
           android : drawselectorOnTop="false" />
 

通过继承ListActivity来实现ListView时,当用户也定义了一个id为@id/android:list的ListView,与ListActivity中的默认ListView组件id一致,则使用setContentViewO方法可以指定用户定义的ListView作为ListActivity的布局,否则会使用系统提供的ListView。


  • 实现图文混排步骤︰

    • 定义行选项的布局格式

    • 自定义一个Adapter,并重写其中的关键方法

    • 注册列表选项的单击事件

    • 创建Activity并加载对应的布局文件


GridView网格视图

  • 用于按行和列的分布方式来显示多个组件

  • 通过Adapter来提供显示数据

XML属性描述android:numColumns设置列数android:columnWidth设置每一列的宽度android:stretchMode设置拉伸模式android:verticalSpacing设置各个元素之间的垂直边距android:horizontalSpacing设置各个元素之间的水平边距

  • 创建GridView的步骤︰

    • 在布局文件中使用<GridView>元素来定义GridView组件

    • 自定义一个Adapter,并重写其中的关键方法

    • 注册列表选项的单击事件

    • 创建Activity并加载对应的布局文件


WebView

  • WebView用于在App中加载网页

  • 使用Web检查器来调试HTML、CSS、Javascript等代码

  • 可以对URL请求、页面加载、渲染以及页面的交互进行处理


  • WebView具有以下几个辅助类:

    • WebChromeClient:辅助WebView实现与浏览器的交互动作

    • WebViewClient:帮助WebView处理各种通知、请求事件等

    • WebSettings : x对WebView进行配置和管理

    • addJavascriptInterface():将Java对象绑定到WebView中,以便JavaScript从页面中控制Java对象,实现WebView与HTML页面的交互


在Android 4.3及以前版本WebView内部采用Webkit渲染引擎,在Android 4.4以上版本采用chromium渲染引擎来渲染View的内容。


  • 使用WebView的步骤:

     <uses-permission android:name="android.permission.INTERNET"/>
     
    • 在布局文件中创建WebView元素

    • 在代码中加载网页

    • 在AndroidManifest.xml中配置访问权限

  • 使用loadData()或loadDataWithBaseURL()方法将HTML代码片段或本地存储的HTML页面内容显示出来

  • loadDataWithBaseURL()不能加载来自网络的内容

    • baseUrl:基础目录

    • data:被加载的内容

    • mimeType :指定资源的媒体类型

    • Encoding :设置网页的编码格式

    • historyUrl :历史记录字段


ViewPager

  • ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view

  • ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类。

  • ViewPager类需要一个PagerAdapter适配器类给它提供数据。

  • ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用


  • 最普通的PagerAdapter需要重写下面的四个方法:

    • ①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来

    • ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了

    • getCount():获得viewpager中有多少个view

    • destroyltem():移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。

    • instantiateItem():

    • isViewFromObject():判断instantiateltem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图



自定义组件

  • Android中所有控件和布局的基类都是View,自定义控件也就是继承View或者View的派生类,然后再重写类中的内部方法。

  • 通常来说自定义控件分为三种:

    • 自定义View:继承View

    • 基于现有组件∶继承View的派生类

    • 组合的方式∶自定义控件中包含了其他的组件

  • 自定义控件绘制过程︰

    • 创建一个类,继承View类

    • onMeasure()方法,测量计算视图的大小

    • onLayout()方法,设置视图在屏幕中显示的位置

    • onDraw()方法,绘制视图

为什么要在安卓中使用自定义控件? 安卓在使用中大多数使用已有的一些控件,用法比较简单,还有一部分是比较复杂的、用户自己想的控件,这些就需要进行自定义控件!


  • 自定义View的方法,有以下十三种:

    • onFinishInflate()︰回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法

    • onMeasure()∶检测View组件及其子组件的大小

    • onLayout():当该组件需要分配其子组件的位置、大小时

    • onSizeChange():当该组件的大小被改变时

    • onDraw():当组件将要绘制它的内容时

    • onKeyDown :当按下某个键盘时

    • onKeyUp :当松开某个键盘时



UI进阶的评论 (共 条)

分享到微博请遵守国家法律