最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析Android中的RecyclerView組件

 更新時(shí)間:2016年06月29日 16:22:47   作者:IDER  
RecyclerView是Android 5.0以來(lái)新加入的組件,被廣泛認(rèn)為是ListView的替代品,這里我們就結(jié)合理論與實(shí)踐來(lái)深入解析Android中的RecyclerView組件:

前些日子,組里為了在目前的Android程序里實(shí)現(xiàn)基于ListView子項(xiàng)的動(dòng)畫(huà)效果,希望將最新的RecyclerView引入到程序中,于是我便花了一些時(shí)間研究了一下RecyclerView的基本情況。本文算是對(duì)這些日子里了解的內(nèi)容做一些匯總。

在網(wǎng)上關(guān)于RecyclerView的基本使用方式已經(jīng)有了比較詳細(xì)介紹,而且其設(shè)計(jì)結(jié)構(gòu)也類似于ListView,所以本文將不重點(diǎn)介紹如何使用,在文末的引用中都可以相關(guān)內(nèi)容。這里主要是介紹RecyclerView的基本功能、設(shè)計(jì)理念,以及系統(tǒng)提供API的情況。

什么是RecyclerView
RecyclerView是在Android L(也就是后來(lái)的Lollipop)中新加入的一種ViewGroup。但因?yàn)樗挂詓upport-v7庫(kù)的形式加入到Android系統(tǒng)中,所以不僅僅是Lollipop版本以后的Android系統(tǒng)可以使用,只要系開(kāi)發(fā)項(xiàng)目中引入這個(gè)庫(kù)就在任意API級(jí)別中使用。不過(guò)查閱其文檔,可以感受到RecyclerView是如此的強(qiáng)烈的“還在完善中”的感覺(jué),因?yàn)閷?duì)它的介紹只有短短的一句話:

A flexible view for providing a limited window into a large data set.

單看這句話,其實(shí)已經(jīng)被經(jīng)常使用的ListView和GridView基本也是滿足這句描述的。而且從單呈現(xiàn)效果來(lái)看RecyclerView和ListView、GridView并沒(méi)有大多的差別。

不過(guò)它的“flexible”并不單單指它可以在ListView和GridView之間隨意互相切換,更在于它可以創(chuàng)造出更多的復(fù)雜的可滾動(dòng)的視圖,比如水平方向的ListView,或者是Web上很流行的瀑布流式布局(Masonry)。只是大部分布局系統(tǒng)都沒(méi)有提供,必須由開(kāi)發(fā)者自己實(shí)現(xiàn)。

所以RecyclerView的“flexible”:什么都可以做,但什么都要自己做。

RecyclerView和ListView的主要區(qū)別
只要用Android提供的LieanerLayoutManager并配以VERTICAL模式,RecyclerView就可以完美達(dá)到ListView的基本效果。兩者的設(shè)計(jì)結(jié)構(gòu)也都是數(shù)據(jù)(Dataset)與視圖(View)分離,然后通過(guò)適配器(Adapter)來(lái)連接的方式。

但RecyclerView相對(duì)ListView來(lái)說(shuō)有以下幾大提升:

強(qiáng)制使用ViewHolder
在ListView性能優(yōu)化方面,Android就推薦使用ViewHolder來(lái)減少findViewById()的使用以提高效率。不過(guò)對(duì)于ListView上的ViewHolder,Android只是建議而非強(qiáng)制使用。不過(guò)因?yàn)槭褂肰iewHolder模式太有意義了,所以在RecyclerView中ViewHolder就變成了必須使用的模式,Adapter要求返回的也從普通的View變成了ViewHolder。不過(guò)如果實(shí)現(xiàn)時(shí)沒(méi)有自定義的一些View實(shí)際變量,ViewHolder也依然失去其意義。

沒(méi)有OnItemClickListener
ListView從它的父類AdapterView直接繼承了對(duì)子項(xiàng)目點(diǎn)擊的響應(yīng),開(kāi)發(fā)者可以定義自己的OnItemClickListner來(lái)接受點(diǎn)擊事件。但這個(gè)設(shè)計(jì)也造成了一些問(wèn)題,比如子項(xiàng)內(nèi)部視圖如果設(shè)置了OnClickListener,那么子項(xiàng)目視圖本身并不會(huì)知道,從而可能會(huì)導(dǎo)致視圖點(diǎn)擊狀態(tài)沒(méi)有同步等問(wèn)題。ReyclerView沒(méi)有提供簡(jiǎn)便的響應(yīng)子項(xiàng)目被點(diǎn)擊的監(jiān)聽(tīng)器,雖然它有一個(gè)OnItemTouchListener,但在這個(gè)接口方法中沒(méi)有任何關(guān)于那個(gè)子項(xiàng)目被點(diǎn)擊的信息,該接口只是幫助開(kāi)發(fā)者截獲觸摸事件,對(duì)于如何處理,檢測(cè)被觸摸目標(biāo)對(duì)象都留給了開(kāi)發(fā)者去完成

視圖與布局分離
ListView做到了數(shù)據(jù)和視圖的分離,RecyclerView在視圖和布局之間再進(jìn)一步分離,于是便有了LayoutManager。RecyclerView負(fù)責(zé)管理視圖的重復(fù)利用,然后將布局方式全權(quán)交給了LayoutManager,通過(guò)配置或者切換LayoutManager就可以獲得不同的布局效果。不像ListView被限制在垂直滾動(dòng)布局。同時(shí)RecyclerView還提供了ItemDecoration,在已有的子視圖基礎(chǔ)上還可以添加額外的視圖。比如做一條分割線,在ListView就需要額外占用一個(gè)ViewType來(lái)提供視圖,現(xiàn)在則不需要在Adapter中加入這些與實(shí)際邏輯業(yè)務(wù)無(wú)關(guān)的輔助內(nèi)容。

支持子項(xiàng)目層次的動(dòng)畫(huà)效果
ListView也可以支持子項(xiàng)目層次的動(dòng)畫(huà)效果,在Android Developers的DevBytes頻道里有很多關(guān)于這方面的介紹,不過(guò)在看過(guò)其實(shí)現(xiàn)之后就會(huì)發(fā)現(xiàn)其解決方案是多么的丑陋而冗長(zhǎng)。很多時(shí)候都是在計(jì)算和分析子視圖的位置狀態(tài)。RecyclerView則帶來(lái)了非常簡(jiǎn)潔的ItemAnimator接口。當(dāng)Adapter中的數(shù)據(jù)發(fā)生“增刪改移”變化,通過(guò)調(diào)用Adapter相應(yīng)的方法就可以激活動(dòng)畫(huà)的產(chǎn)生。當(dāng)然開(kāi)發(fā)者還需要自己實(shí)現(xiàn)具體的ItemAnimator對(duì)象來(lái)完成所需的動(dòng)畫(huà)效果,但是其清晰的結(jié)構(gòu)和接口已比ListView有極大的進(jìn)步。

RecyclerView的現(xiàn)狀
上邊提到RecyclerView的套件已經(jīng)加入了豪華Support Library v7,而且是以單獨(dú)的庫(kù)放入,所以只要在Android Studio項(xiàng)目的Gradle編譯文件的dependencies下加入下邊的這句就可以開(kāi)始使用RecyclerView了:

compile 'com.android.support:recyclerview-v7:21.0.+'
不過(guò)看過(guò)庫(kù)中提供的那些自帶對(duì)象實(shí)現(xiàn),體現(xiàn)基本操作流程,就會(huì)發(fā)現(xiàn)RecyclerView能做的看起來(lái)很多,但是已經(jīng)做到的實(shí)在太少。

RecyclerView.Adapter

RecyclerView提供了一個(gè)抽象Adapter類,然后就沒(méi)有了。沒(méi)有任何可以直接使用的子類,像ListAdapter那樣的ArrayAdapter、SimpleCursorAdapter現(xiàn)成的類都沒(méi)有。一切都留給開(kāi)發(fā)者自己去實(shí)現(xiàn)定義。

仔細(xì)想想這也很挺正常,相信應(yīng)該很少在實(shí)際產(chǎn)品中有使用ArrayAdapter的,因?yàn)榇蟛糠至斜矶疾粫?huì)是簡(jiǎn)單的一行文字。對(duì)于CursorAdapter使用也往往會(huì)實(shí)現(xiàn)不同的繼承類來(lái)提供子視圖。再者RecyclerView的Adapter和ListAdapter在理念上還是一樣的,所以想實(shí)現(xiàn)個(gè)RecyclerViewCursorAdapter,直接從CursorAdapter取材便可。

RecyclerView的Adapter相對(duì)ListAdapter在接口上有幾處變化也值得注意。

首先其將getView()方法分拆成了createViewHolder()和bindViewHolder()兩個(gè)。不過(guò)這個(gè)沒(méi)有什么好緊張的,在CursorAdapter里就已經(jīng)有見(jiàn)到過(guò)這個(gè)更加合理的設(shè)計(jì)。另外返回對(duì)象也從View變成了ViewHolder只需提一下。

最關(guān)鍵的注意點(diǎn)在于createViewHolder(ViewGroup parent, int viewType)第二參數(shù)雖然是整形,但是它并不是以往的當(dāng)前子項(xiàng)的位置(position),而是調(diào)用getItemViewType()獲得的的子項(xiàng)的類別。似乎在創(chuàng)建ViewHolder時(shí),RecyclerView故意在隱藏子項(xiàng)的詳細(xì)信息,希望開(kāi)發(fā)者完全只依賴其類別來(lái)創(chuàng)建相應(yīng)的View以及ViewHolder。

其次,RecyclerView的Adapter除了和ListAdapter一樣有notifyDataSetChanged()方法外,還有一堆會(huì)觸發(fā)動(dòng)畫(huà)效果的通知數(shù)據(jù)改變的方法:

  • final void notifyItemChanged(int position);
  • final void notifyItemInserted(int position);
  • final void notifyItemMoved(int fromPosition, int toPosition);
  • final void notifyItemRangeChanged(int positionStart, int itemCount);
  • final void notifyItemRangeInserted(int positionStart, int itemCount);
  • final void notifyItemRangeRemoved(int positionStart, int itemCount);
  • final void notifyItemRemoved(int position);

調(diào)用這些方法就會(huì)激發(fā)ItemAnimator上對(duì)應(yīng)的用于產(chǎn)生動(dòng)畫(huà)的方法。

RecyclerView.ViewHolder

在ListView的年代里,其實(shí)已經(jīng)在使用ViewHolder,只是那時(shí)的方法看起來(lái)比較討巧,要隱藏在View的tag里。現(xiàn)在RecyclerView強(qiáng)制使用ViewHolder,并且ViewHolder除了有對(duì)子視圖的引用,還有諸如ItemViewType和Position這些信息。

RecyclerView.LayoutManager

LayoutManager相對(duì)于ListView來(lái)說(shuō)是一個(gè)新部分,通過(guò)繼承該類來(lái)實(shí)現(xiàn)自定義的布局方式,而不像ListView只有固定的布局方式。Support庫(kù)提供了兩個(gè)現(xiàn)成的子類:LinearLayoutManager和StaggeredGridLayoutManager。前者可以獲得和ListView一樣的布局,還可以是水平方向的;后者則提供了形如GridView的布局。所以應(yīng)用程序中的基本日常所以都可以被滿足。

如果需要實(shí)現(xiàn)自定義的LayoutManager,就比較麻煩了,需要理解Recycle、Scrap、Dirty這些關(guān)于子項(xiàng)目視圖狀態(tài)的概念。本人還沒(méi)有嘗試過(guò)創(chuàng)建一個(gè)自定義的LayoutManager,但在文末的引用文檔中有部分介紹實(shí)現(xiàn)方式的。

RecyclerView.ItemAnimator

通過(guò)實(shí)現(xiàn)繼承實(shí)現(xiàn)ItemAnimator,然后創(chuàng)建對(duì)象設(shè)置到RecyclerView上就可以得到基于子項(xiàng)目的動(dòng)畫(huà)效果。不過(guò)如何正確合理地創(chuàng)建一個(gè)ItemAnimator子類,卻沒(méi)有詳細(xì)的描述指南。

窺探庫(kù)中提供的唯一一個(gè)可用的子類DefaultItemAnimator,可以看出它的動(dòng)畫(huà)效果是簡(jiǎn)單的alpha漸變。同時(shí)也會(huì)發(fā)現(xiàn)其實(shí)現(xiàn)是如此的復(fù)雜,有很多對(duì)于動(dòng)畫(huà)步驟的操作,還得注意動(dòng)畫(huà)在中途被打斷的處理,在結(jié)束時(shí)也要重置視圖狀態(tài)以便重用。這也反過(guò)來(lái)說(shuō)明ItemAnimator基本沒(méi)有提供任何關(guān)于如何實(shí)現(xiàn)和管理動(dòng)畫(huà)的信息。另一方面因?yàn)镈efaultItemAnimator的實(shí)現(xiàn)過(guò)于具體,因此它并不是合適作為自定義ItemAnimator的父類。

相信當(dāng)RecyclerView越來(lái)越多的被應(yīng)用到程序中時(shí),更多關(guān)于這方面的合理設(shè)計(jì)會(huì)被提出來(lái)。目前在Github上也有不少參考了DefaultItemAnimator的實(shí)現(xiàn)方式,比如這個(gè),還有這個(gè)。

關(guān)于ItemAnimator的使用,有幾點(diǎn)值得提醒的是:如果沒(méi)有提供ItemAnimator,RecyclerView默認(rèn)會(huì)創(chuàng)建一個(gè)DefaultItemAnimator用于動(dòng)畫(huà),所以不需要顯示地設(shè)置DefaultItemAnimator對(duì)象到RecyclerView上;添加(add)和刪除(remove)是默認(rèn)起效的,但是修改(change)的效果需要調(diào)用setSupportsChangeAnimations(boolean)來(lái)指定是否啟用,其默認(rèn)是沒(méi)有修改的動(dòng)畫(huà)。

總體而言,RecyclerView的功能非常強(qiáng)大,其結(jié)構(gòu)設(shè)計(jì)也十分開(kāi)放,這也造成它的上手使用相對(duì)比較困難。隨著越來(lái)越多的人開(kāi)始嘗試使用這個(gè)部件,也會(huì)有越來(lái)越深刻的理解和設(shè)計(jì)實(shí)現(xiàn)。另外,閱讀RecyclerView的源碼可以幫助對(duì)其設(shè)計(jì)思想的了解,在以后設(shè)計(jì)其它的復(fù)用視圖時(shí)可以有更好的參照。

DEMO

說(shuō)了這么多,我們來(lái)看一個(gè)RecyclerVIew實(shí)現(xiàn)圖片文字按鈕的混排的demo:

2016629161652878.jpg (250×404)

首先還是看我的工程結(jié)構(gòu)吧。

2016629161719331.jpg (281×707)

首先還是貼出我的main_acitivy.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

 <!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
 android:id="@+id/my_recycler_view"
 android:scrollbars="vertical"
 android:layout_width="match_parent"
 android:layout_height="match_parent"/>
</LinearLayout>

其他幾個(gè)xml就不用貼了,很簡(jiǎn)單的放了寫(xiě)TextVIew,ImgeView之類。

然后我們就來(lái)看看代碼,首先是Bean里面的代碼。

package com.androidl.bob;

public class Bean {
 public static final int Y_TYPE = 0; //view類型0
 public static final int X_TYPE = 1; //view類型2
 public static final int Z_TYPE = 2;//view 類型3
 private int type;
 private String text;

 public Bean(int type, String text) {
  super();
  this.type = type;
  this.text = text;
 }

 public int getType() {
  return type;
 }

 public void setType(int type) {
  this.type = type;
 }

 public String getText() {
  return text;
 }

 public void setText(String text) {
  this.text = text;
 }

}

然后是Adapter里面的代碼:

package com.androidl.bob;

import java.util.List;

import com.example.androidl.R;

import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Date : 2014/7/15
 * 
 * @author edsheng
 * 
 */
public class RecycleAdapter extends RecyclerView.Adapter<ViewHolder> {

 private List<Bean> beans;

 public RecycleAdapter(List<Bean> beans) {
  super();
  this.beans = beans;
 }

 /**
  * 內(nèi)部TextHoler
  * 
  * @author edsheng
  * 
  */
 public class TextHoler extends RecyclerView.ViewHolder {
  public TextView textView;

  public TextHoler(View textview) {
   super(textview);
   this.textView = (TextView) textview.findViewById(R.id.mytext);
  }
 }

 /**
  * iamgeHolder
  * 
  * @author edsheng
  * 
  */
 public class ImageHoler extends RecyclerView.ViewHolder {
  public ImageView Imageview;

  public ImageHoler(View textview) {
   super(textview);
   this.Imageview = (ImageView) textview.findViewById(R.id.myiamge);
  }
 }

 /**
  * 按鈕的holder
  * 
  * @author edsheng
  * 
  */
 public class ButtonHolder extends RecyclerView.ViewHolder {
  public Button button;

  public ButtonHolder(View textview) {
   super(textview);
   this.button = (Button) textview.findViewById(R.id.mybutton);
  }
 }

 @Override
 public int getItemCount() {
  // TODO Auto-generated method stub
  return beans.size();
 }

 /**
  * 獲取消息的類型
  */
 @Override
 public int getItemViewType(int position) {
  // TODO Auto-generated method stub
  return beans.get(position).getType();
 }

 /**
  * 創(chuàng)建VIewHolder
  */
 @Override
 public ViewHolder onCreateViewHolder(ViewGroup parent, int viewtype) {
  // TODO Auto-generated method stub
  View v = null;
  ViewHolder holer = null;
  switch (viewtype) {
  case Bean.X_TYPE:
   v = LayoutInflater.from(parent.getContext()).inflate(
     R.layout.recylce_item_x, null);
   holer = new TextHoler(v);
   break;
  case Bean.Y_TYPE:
   v = LayoutInflater.from(parent.getContext()).inflate(
     R.layout.recylce_item_y, null);
   holer = new ButtonHolder(v);
   break;
  case Bean.Z_TYPE:
   v = LayoutInflater.from(parent.getContext()).inflate(
     R.layout.recylce_item_z, null);
   holer = new ImageHoler(v);
   break;
  }

  return holer;
 }

 /**
  * 綁定viewholder
  */
 @Override
 public void onBindViewHolder(ViewHolder holder, int position) {
  // TODO Auto-generated method stub
  switch (getItemViewType(position)) {
  case Bean.X_TYPE:
   TextHoler textholer = (TextHoler) holder;
   textholer.textView.setText(beans.get(position).getText());
   break;
  case Bean.Y_TYPE:
   ButtonHolder buttonHolder = (ButtonHolder) holder;
   buttonHolder.button.setText(beans.get(position).getText());
   break;
  case Bean.Z_TYPE:
   ImageHoler imageHoler = (ImageHoler) holder;
   // imageHoler.Imageview.setImageResource(android.R.drawable.checkbox_on_background);
   break;
  }
 }
}

最后是activity的代碼。

package com.androidl.bob;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.example.androidl.R;

public class Mainactivity extends Activity {
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main_activity);
   RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

// // improve performance if you know that changes in content
// // do not change the size of the RecyclerView
//  mRecyclerView.setHasFixedSize(true);

   //創(chuàng)建布局管理器
  LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
  mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
  mRecyclerView.setLayoutManager(mLayoutManager);

  //初始化數(shù)據(jù)
  List<Bean> myDataset = new ArrayList<Bean>();

  myDataset.add(new Bean(Bean.Z_TYPE, "圖片"));
  myDataset.add(new Bean(Bean.X_TYPE, "文字"));
  myDataset.add(new Bean(Bean.Y_TYPE, "按鈕"));
  myDataset.add(new Bean(Bean.Z_TYPE, "圖片"));
  myDataset.add(new Bean(Bean.X_TYPE, "shit"));
  myDataset.add(new Bean(Bean.X_TYPE, "我擦"));
  myDataset.add(new Bean(Bean.Z_TYPE, "圖片"));
  myDataset.add(new Bean(Bean.Y_TYPE, "按鈕"));
  myDataset.add(new Bean(Bean.Y_TYPE, "按鈕"));
  myDataset.add(new Bean(Bean.X_TYPE, "文字"));
  //創(chuàng)建Adapter
  RecycleAdapter mAdapter = new RecycleAdapter(myDataset);
  mRecyclerView.setAdapter(mAdapter);

 }

} 

相關(guān)文章

  • 詳解四種主要的Android依賴管理方式

    詳解四種主要的Android依賴管理方式

    Android應(yīng)用開(kāi)發(fā)涉及大量的依賴庫(kù)和第三方組件,因此有效地管理這些依賴關(guān)系至關(guān)重要,本文將介紹四種主要的Android依賴管理方式,分析它們的優(yōu)點(diǎn)、缺點(diǎn)以及最佳實(shí)踐,需要的朋友可以參考下
    2023-09-09
  • Android應(yīng)用開(kāi)發(fā):電話監(jiān)聽(tīng)和錄音代碼示例

    Android應(yīng)用開(kāi)發(fā):電話監(jiān)聽(tīng)和錄音代碼示例

    這篇文章主要介紹了Android應(yīng)用開(kāi)發(fā)中電話監(jiān)聽(tīng)和電話錄音的代碼實(shí)例,同時(shí)附錄了一個(gè)拍照、錄像的例子,需要的朋友可以參考下
    2014-04-04
  • Android5.1 取消錄制屏幕跳出的權(quán)限對(duì)話框問(wèn)題

    Android5.1 取消錄制屏幕跳出的權(quán)限對(duì)話框問(wèn)題

    這篇文章主要介紹了Android5.1 取消錄制屏幕跳出的權(quán)限對(duì)話框問(wèn)題,需要的朋友可以參考下
    2017-04-04
  • android中ProgressDialog與ProgressBar的使用詳解

    android中ProgressDialog與ProgressBar的使用詳解

    本篇文章是對(duì)android中ProgressDialog與ProgressBar的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Android手機(jī)內(nèi)存中文件的讀寫(xiě)方法小結(jié)

    Android手機(jī)內(nèi)存中文件的讀寫(xiě)方法小結(jié)

    這篇文章主要介紹了Android手機(jī)內(nèi)存中文件的讀寫(xiě)方法,實(shí)例總結(jié)了Android針對(duì)文件讀寫(xiě)操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Android中如何取消listview的點(diǎn)擊效果

    Android中如何取消listview的點(diǎn)擊效果

    這篇文章主要介紹了 Android中取消listview的點(diǎn)擊效果的實(shí)現(xiàn)方法,通過(guò)引用transparent之后會(huì)讓點(diǎn)擊效果透明化,一起通過(guò)本文學(xué)習(xí)吧
    2017-01-01
  • Android延時(shí)操作的三種方法

    Android延時(shí)操作的三種方法

    這篇文章主要為大家詳細(xì)介紹了Android延時(shí)操作的三種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 解決android studio卡頓,提升studio運(yùn)行速度的方法

    解決android studio卡頓,提升studio運(yùn)行速度的方法

    這篇文章主要介紹了解決android studio卡頓,提升studio運(yùn)行速度的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • Handler與Android多線程詳解

    Handler與Android多線程詳解

    一開(kāi)始,相信很多人都以為myThread中的run()方法會(huì)在一個(gè)新的線程中運(yùn)行,但事實(shí)并非如此。以下代碼中的handler并沒(méi)有調(diào)用線程myThread的start()方法,而是直接調(diào)用了run()方法,這也就意味著實(shí)際上并沒(méi)有創(chuàng)建一個(gè)新的線程,只是在當(dāng)前線程中調(diào)用run()方法而已
    2013-10-10
  • flutter封裝點(diǎn)擊菜單工具欄組件checkBox多選版

    flutter封裝點(diǎn)擊菜單工具欄組件checkBox多選版

    這篇文章主要為大家介紹了flutter封裝一個(gè)點(diǎn)擊菜單工具欄組件,checkBox多選版的示例示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05

最新評(píng)論

同仁县| 晋中市| 天柱县| 建宁县| 苏尼特左旗| 尚义县| 呼图壁县| 徐汇区| 屏南县| 铜陵市| 睢宁县| 申扎县| 昌平区| 江油市| 临夏县| 澎湖县| 小金县| 方城县| 凌源市| 沈丘县| 巴楚县| 长宁区| 类乌齐县| 沭阳县| 吉木乃县| 杭锦后旗| 兰州市| 凉山| 南陵县| 嘉鱼县| 股票| 华阴市| 太谷县| 东光县| 沈阳市| 长丰县| 洛阳市| 楚雄市| 长武县| 虹口区| 怀仁县|