2.Activity启动模式+Intent+AsylncTask+ListView

一.Activity的启动模式  两种方式四种模式

(1)在清单文件中,标签中配置android:launchMode=""属性

     四个属性值:

     <1>standard:

                            默认的  可以实例化多次,每次启动都会创建一个新的实例

     <2>singleTop:

                             可以实例化多次,当其在栈顶时,只能创建一个实例

                             当栈顶存在要启动的Activity实例时,系统会调用onNewIntent()方法

                             把Intent对象传递给已经存在的Activity实例,从而重用栈顶的Activity

      <3>singleTask:

                                栈内部只能有一个Activity实例,

                                解释一:当第二次启动该Activity时,系统会从上到下依次寻找该Activity已有的实例,

                                找到会移除它之上的所有Activity实例,并重用该Activity实例

                                解释二:当栈中存在要启动的Activity实例时,系统会调用onNewIntent() 方法

                                把Intent对象传递给已经存在的Activity实例,从而重用该Activity实例

       <4>singleInstance:

                                系统会单独分配一个任务栈,并把它的实例放到栈底,不和别的Activity共享一个栈

(2)在Activity类中通过Intent对象设置启动模式,优先级高于上面的方式

        Intent intent = new Intent();

        intent.setFlags(Intent.参数);

参数:

          默认                      等同于standard

          FLAG_ACTIVITY_SINGLE_TOP  等同于singleTop

          FLAG_ACTIVITY_CLEAR_TOP  等同于singleTask

          FLAG_ACTIVITY_NEW_TASK    等同于singleInstance

          如果是代码中设置启动模式:NEW_TASK,则必须在清单文件中加上下面属性

          android:taskAffinity="com.other"

          android:allowTaskReparenting="true"

          否则不起作用

二.Intent七大属性

(1)Intent的作用

      包装android的组件

      启动Activity ,启动Service,发送广播

     组件之间的传值

(2)显示意图------setClass()

                     ------setComponent();

明确指定要跳转到哪个Activity(通常用于启动应用内部的Activity)

写法一: Intent intent = new Intent(MainActivity.this,InfoActivity.class);

写法二: Intent intent= new Intent();

                 intent.setClass(MainActivity.this,InfoActivity.class);

写法三:  ComponentName 包装Android组件

               Intent intent = new Intent();

               ComponentName cn = new  ComponentName(MainActivity.this,InfoActivity.class);

               intent.setComponent(cn);

(3)隐身意图------action      

     不明确指定目标Activity,而是通过Intent的动作action(通常用于多个应用程序之间的跳转)      

     必须在android应用中保持唯一      

    目标Activity中必须声明action属性

     <intent-filter>

           <action   android:name="com.qf.day06_lunchmode.CActivity"/>

           <category  android.intent.category.DEFAULT"/>

     </intent-filter>

注意:action属性一般需要和category属性一起使用

访问者:

方式一: Intent intent=new  Intent();

                Intent();intent.setAction("com.qf.day06_lunchmode.CActivity");        

方式二:                

              Intent intent  = new Intent("com.qf.day06_lunchmode.CActivity");                     

              android.setting.SETTINGS 设置页面

              Intent.ACTION_DIAL      拨号页面

              Intent.ACTION_CALL      拨打电话(直接呼出)

(4)category:表示action组件启动的类型

            一般android.intent.category.DEFAULT 代表普通的Activity组件

(5)data属性:指定action后,将必须的属性设置在此属性中

          如:打电话  必须提供电话号码

               打开网页    网址

         URI  统一资源标识

                 打电话: tel:53435343443

                 发短信: smsto:760439045

                 网址:  http://www.baidu.com

(6)type属性:

           如果data属性是文件的路径,必须通过type来指定文件的类型

           图片:  image/*

           文本:  text/*

           视频:  video/*

           音频:  audio/*

(7)extra 属性:除了必须的属性之外的扩展信息的属性

              常用于Android组件之间传递数据

(8)flag:组件的启动模式 (参考Activity的启动模式)

            广播接收器,启动Activity组件式,必须指定flag属

           性:FLAG_ACTIVITY_NEW_TASK

三.AsyncTask的使用

(1)定义一个类,继承AsyncTask类,同时声明三个泛型      

public class MyAsyncTask extends AsyncTask<String,Integer,Byte[]>

第一个参数:  子线程执行方法的参数类型,对应doinbackground的参数

第二个参数:  子线程执行方法的进度,    对应onProgressUpdate的参数  可以为空,Void首字母应该大写

第三个参数:  子线程执行任务的结果返回类型,对应onPostExecute的参数和doInbackground的返回值

(2)AsyncTask的四个核心方法(重写)

        //运行在主线程中,执行异步任务时,首先调用的方法,用于初始化

       <1>protected void onPreExecute()//运行在子线程中,执行耗时的操作(后台线程)

       <2>protected byte[] doInBackground(String... params)//运行在主线程中,用于更新                                                                                                       进度,更新前必须先手动                                                                                                         调用publishProgress()方                                                                                                          法

      <3>protected void onProgressUpdate(Integer...values)//运行在主线程中,在                                                                                                                   doInbackground方法之后                                                                                                       执行,系统自动调用

      <4>protected void onPostExecute(byte[] result)

(3)利用回调接口来实时更新进度

<1>定义一个回调接口

       public interface CallBack{

                     public void callBack(int progress);回调方法,参数为进度的百分比

       }

<2>在访问网络的工具中声明回调接口(HttpUtils工具类)

public  static String getJson(String path,CallBack callback){//以加载json字符串为例

          //获取网络资源的代码

         //调用CallBack接口中的回调方法传回进度

         callback.callBack(progress);

}

<3>在doInBackground方法中调用getJson方法,同实例化一个CallBack接口的匿名内部类

protected byte[] donInBackground(String ... params){

           HttpUtils.getJson(params[0],new CallBack(){

                            public void callBack(int progress){

                                   //当获取网络资源的代码中调用此回调接口时,触发此处代码,并                                        传回进度

                                  //拿到进度值,更新进度条

                                publishProgress(progress); //该方法将触发                                                                                                                    onProgressUpdate(Integer..values);方法

                            }

             });

}

(4)取消异步任务

        (1)调用task.cancel(true);//true表示暴力取消,false温柔取消

        (2)温柔取消时系统会自动执行onCancelled()方法

              protected void onCancelled() {

                             if(isCancelled()){

                                 Toast.makeText(MainActivity.this, "任务被取消!",                                                                                                          Toast.LENGTH_LONG).show();

                             }

              }

四.ListView的总结

(1)主要属性:

                  android:divider = "#rgb"  Item之间的分割线的颜色,也可以是一张图片

                  android:dividerHeight = "1dp" Item之间的距离,通常为1dp

                  android:entries="@array/name"  用数组填充Item

(2)填充方式:      

         <1>属性填充:          

                step1:先在strings.xml中定义数组

                           <string_array name="citys">

                           <item>北京</item>

                           </string_array>

               step2:在listView中添加entries属性       

                          android:entries="@array/citys"

           <2>在Activity中通过适配器填充          

                 ①ArrayAdapter填充,适用于Item中只有一个文本    数据源为:List<String>

                 ②SimpleAdapter填充,可以实现图文混排的效果,但图片必须是本地的(不能是从网络获取的)    数据源为:List<Map<String,Object>>

 ③自定义Adapter,创建自己的Adapter类继承BaseAdapter抽象类,实现抽象方法    数据源为:List<Map<String,Object>>或者ListM<javaBean>

         Step1:定义一个类继承BaseAdapter

         Step2:实现四个抽象方法

                     getCount()得到数据源的总长度

                     getItem(int position)得到下标对应的Item

                     getItemId(int position)得到下标对应的Item的Id

                     getView(int position,View convertView,ViewGrioup parent)

          step3:在getView方法中为每个Item配置布局和数据

(3)ListView的事件监听器

         ①Item单击响应事件

             OnItemClickListener

         ②Item长按响应事件

             OnItemLongClickListener

         ③ListView滚动事件

              listview.setOnScrollListener(new OnScroolListener()){

                     //该方法监听listView滚动状态的改变

                     //AbsListView ----- listView

                     //int scrollState----滚动的状态

                     //三种滚动状态对应三个状态码

                    //OnScrollListener.SCROLL_STATE_TOUCH_SCROLL------1 listView正                       在滑动且手指还在屏幕上

                    //OnScrollListener.SCROLL_STATE_FLING --------2  listView惯性滑动

                    //OnScrollListener.SCROLL_STATE_IDLE  --------0  listView停止滑动

                   public void onScrollStateChanged(AbsListView view,int scrollState){

                   }

                   //该方法监听listView滚动的方法

                   //AbslistView view------listView

                  //int firstVisibleItem ------当前屏幕最上方显示的Item的下标

                  //int visibleItemCount ------当前屏幕显示Item的个数,半个也算

                  //int totalItemCount  -------当前所有Item的总数

                  public void onScroll(AbsListView view,int firstVisibleItem,

                                                                int visibleItemCount,int totalItemCount){

                              //小技巧:判断是否滑动到最底部

                             Boolean islast = (firstVisible+visibleItemCount==totalItemCount);

                  }

}

(4)ListView 的优化

①属性优化:

                    android:layout_width="match_parent"

                    android:layout_height="match_parent"

                     如果是wrap_content,加载时每条Item会执行多次来计算ListView的宽高

②重用convertView对象,将Item布局缓存起来从而复用

③定义ViewHolder类,减少findViewById的次数

参考代码:

public View getView(int position, View convertView, ViewGroup parent) {

                    ViewHolder holder;

                    if (convertView == null) {

                                       holder = new ViewHolder();

                                       convertView = View.inflate(context, R.layout.item_listview, null);

                                       holder.textViewName = (TextView)                                                                                                                     convertView.findViewById(R.id.name);

                                        holder.textViewDescription = (TextView)                                                                                                          convertView.findViewById(R.id.description);

                                       convertView.setTag(holder);

                       } else {

                                        holder = (ViewHolder) convertView.getTag();

                      }

                      holder.textViewName.setText(list.get(position).getName());

                      holder.textViewDescription.setText(list.get(position).getDescription());

                      return convertView;

}

(5)ListView加载网络图片,实现图文混排

通常图片地址在Json数据中或者XML文件中.(以json为例)

<1>通过网络加载json数据,然后解析封装成类

<2>在ListView的Adapter中构建Item时,

如果是文本内容则直接设置,如果为图片内容则开启异步任务去网络中加载

<3>对加载好的图片进行缓存,当第二次需要展示的时候,直接在内存中加载而不用访问网络

此处用Map来缓存(只是模拟),其他缓存方式后续更新

<4>由于convertView的复用,和异步任务形成的时间差,会造成图片错位现象

通过为ImageView打标签可以解决图片错位的问题

代码:  

Map<String,Bitmap> map = new HashMap<String,Bitmap>();

ViewHolder holder;

public View getView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {

                            holder = new ViewHolder();

                            convertView = View.inflate(context, R.layout.item_listview, null);

                            holder.imageView = (ImageView)                                                                                                              convertView.findViewById(R.id.image);

                            holder.textViewName = (TextView) convertView

                                                                            .findViewById(R.id.name);

                            convertView.setTag(holder);

               } else {

                             holder = (ViewHolder) convertView.getTag();

               }

               holder.imageView.setImageResource(R.drawable.ic_launcher);//用于清空被                                                                                             重用的holder中携带的图片内容

               String curImageUrl = list.get(position).getCoverUrl();

               holder.imageView.setTag(curImageUrl);//为ImageView打标签,用此                                                                                                imageView要显示图片的地址最为标签

               if (!map.containsKey(curImageUrl)) {//判断Map中是否存有该地址(图片资源)

                         //如果Map中没有缓存,说明是第一次加载此图片,需要从网络获取

                         new ImageAsyncTask(new CallBack() {//开启异步任务加载图片

                                      @Override

                                       public void callBack(String path, Bitmap bitmap) {

                                                     //通过回调方法返回加载图片资源和其地址

                                                    //将加载好的图片资源和地址存入Map进行缓存

                                                    map.put(path, bitmap);

                                                    ImageView imageView = (ImageView)                                                                                                                     listView.findViewWithTag(path);

                                                    //通过标签在ListView中找到对应的imageView,并为其                                                        设置图片资源

                                                   if (imageView != null) {

                                                                     imageView.setImageBitmap(bitmap);

                                                   }

                                           }

                                  }).execute(curImageUrl);

                  } else {

                              //如果Map中缓存的有需要的图片,则直接拿过来使用

                               holder.imageView.setImageBitmap(map.get(curImageUrl));

               }

               holder.textViewName.setText(list.get(position).getName());

                return convertView;

}

class ViewHolder {

                    ImageView imageView;

                   TextView textViewName;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容