Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 淺談android中的ListView之解決ScrollView和ListView嵌套沖突(一)

淺談android中的ListView之解決ScrollView和ListView嵌套沖突(一)

編輯:關於Android編程

相信大家都已經可以熟練使用ListView和GridView,大神們估計都在使用RecyclerView了。如果還在使用ListView,你肯定有這樣的一個深刻的感受,那就是在做一個APP的時候使用ListView和GridView很頻繁,並且經常會遇到一個頁面中除了有ListView或GridView可能還有一些其他的內容,但是可能內容很多,你第一時間就會想到讓它整體滑動即可,那就是在總的布局外面包裹一個ScrollView。也就是出現了ScrollView中嵌套一個ListView的場景,或者你的ScrollView嵌套多個ListView或者GridView的時候。我們自認為出現場景應該是整體內容會滑動,但是你會驚訝的發現並不是這樣的,你會發現如果是嵌套了一個ListView或者GridView的時候,ListView只會顯示一個Item項,GridView也會只顯示一行。看來我們還是錯了,具體是什麼樣子的下面我們通過一個demo來看看,然後分析一下為什麼會出現這樣的結果,以及最後解決的辦法。

我就簡單寫了一個ListView只要能說明問題即可,至於ListView的優化等問題不是本篇博客的重點,將會在後續的博客出現。

布局文件(注意:仔細看清楚ListView的layout高度的屬性是warp_content)



    

    

        

            

            

                

                    

                    

                    

                    

                    

                    
                

                
            

            
            
        
    

MainActivity.java

package com.mikyou.listviewtest;

import com.mikyou.utils.SystemStatusManager;

import android.app.Activity;
import android.database.DataSetObserver;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView  mListView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setTranslucentStatus();
		setContentView(R.layout.activity_main);
		initData();
		initView();
	}
	private void initView() {
		mListView=(ListView) findViewById(R.id.listview);
		mListView.setAdapter(new MyAdapter());
	}
	class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			return 7;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view=View.inflate(MainActivity.this, R.layout.home_list_item, null);
			return view;
		}

	}
	private void initData() {

	}
	private void setTranslucentStatus() {//沉浸標題欄效果
		// TODO Auto-generated method stub
		if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
			Window win=getWindow();
			WindowManager.LayoutParams winParams=win.getAttributes();
			final int bits=WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
			winParams.flags |=bits;
			win.setAttributes(winParams);
		}
		SystemStatusManager tintManager = new SystemStatusManager(this);
		tintManager.setStatusBarTintEnabled(true);
		tintManager.setStatusBarTintResource(0);
		tintManager.setNavigationBarTintEnabled(true);
	}
}


運行的結果:

\

注意:你會發現只會顯示一個,而我的設置adapter的時候明明設置的是7個,為什麼只顯示一個呢??這是為什麼,這就是意味ListView和ScrollView的嵌套帶來的問題,因為ListView和GridView本身就是繼承於ScrollView,而ScrollView中再次嵌套一個ScrollVewi就會出現高度測量的問題,我們都知道ListView也可以上下滑動,當ListView中的內容很多的時候,屏幕不足以顯示的時候才會滑動顯示。那為什麼只會顯示一項呢?其實仔細分析一下很簡單就是ListView高度不夠,如果高度達到一定的話,就會出現其他的Item項,注意看我們的布局ListView的Wrap_content,也就是測量裡面的內容的高度來得到的,也就對應著android中的VIew測量的模式中的AT_MOST,這種測量模式實際上系統是不會給你真正的測的,而是根據測量其內部的內容來給出一個適合的尺寸,是系統只會測EXACTLY模式即為對應match_parent和指定明確的尺寸。我們還知道ListView每個Item加載模式通過getView方法一個一個的加載出來的,也就是當你第一個Item加載完後,它只測量第一個Item,所以只顯示第一個Item,因為高度不夠,只能顯示第一個。如果不信,我們可以作如下的兩個實驗,第一打印出此時ListVIew的高度看看是不是此時ListView的高度是不是等於第一個Item的高度,第二就是我不指定warp_content,我指定一個明確尺寸看看。

第一個實驗:比較第一個Item高度和ListVIew總高度,來說明此時ScrollView測量第一個Item來作為整個ListView的高度。

通過給ListView添加getViewTreeObserver().addOnGlobalLayoutListener事件,然後在回調方法中去得到高度,注意:因為我們直接或者間接在Activity中的OnCreate方法中去得到高度是為0,因為此時Activity中的View窗體樹並沒有繪制完畢,該方法就是通過監聽整個View的樹繪制完畢後才會回調,所以在該方法才能得到高度

package com.mikyou.listviewtest;

import com.mikyou.utils.SystemStatusManager;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView  mListView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setTranslucentStatus();
		setContentView(R.layout.activity_main);
		initData();
		initView();
	}
	private void initView() {
		mListView=(ListView) findViewById(R.id.listview);
		mListView.setAdapter(new MyAdapter());
		//
		mListView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

			@Override
			public void onGlobalLayout() {
				View firstItemView=mListView.getAdapter().getView(0, null, mListView);//得到第一個Item
				firstItemView.measure(0, 0);
				System.out.println("第一個Item的高度:"+firstItemView.getMeasuredHeight());
				System.out.println("mListView的高度:"+mListView.getHeight());				
			}
		});
	}
	class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			return 7;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view=View.inflate(MainActivity.this, R.layout.home_list_item, null);
			return view;
		}

	}
	private void initData() {

	}
	private void setTranslucentStatus() {//沉浸標題欄效果
		// TODO Auto-generated method stub
		if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
			Window win=getWindow();
			WindowManager.LayoutParams winParams=win.getAttributes();
			final int bits=WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
			winParams.flags |=bits;
			win.setAttributes(winParams);
		}
		SystemStatusManager tintManager = new SystemStatusManager(this);
		tintManager.setStatusBarTintEnabled(true);
		tintManager.setStatusBarTintResource(0);
		tintManager.setNavigationBarTintEnabled(true);
	}
}


在Logcat中打印出來的結果是:

 

\

所以第一個實驗證明咱們的觀點是正確的

那麼接下進行第二個實驗:通過修改布局文件中的ListView的Layout_Height屬性,我們指定明確尺寸看看會發生什麼?



    

    


        

            

            

                

                    

                    

                    

                    

                    

                    
                

                
            

            
            
        
    

 

運行結果和Logcat打印的結果:

\

\

大家會看到這時候就出現了2個Item,但是最後一個Item的還是顯示不夠完全,這因為我們的高度還是不夠,我們在布局文件指定了ListView的高度為300dp,會發現logcat 輸出的高度600,這個就是另外的知識了,因為最後打印出來以及View繪制的尺寸都是Px為單位的,但是這個dp實際上就是邏輯單位,這也是為了兼容和適配Android中眾多不同手機分辨率。由於在不同的手機分辨率中PX和DP換算率也不一樣,由於我的模擬器是1280*768的尺寸,他們換算率為1:2,也就是1dp等於2px,我們設置了300dp,所以打印出來就是600,這樣能解釋為什麼這第二Item顯示不完全,因為一個Item需要321px,兩個就是641px,而我們設置300dp也就是600px小於641px所以肯定顯示不完全了。

通過如下分析,本以為可以找到一個解決辦法,它也確實可以顯示出其他的Item,但是有個很大的問題就是你知道每個Item的高度嗎?由於每個不同ListView中的Item的樣式不一樣,高度自然就不一樣,難道我們每次都去寫死它的高度嗎?而且如果從網絡中獲取數據,Item的個數也是在變得,整個ListVIew的高度也是在變的。那麼這個方法就斷了嗎?其實不然,我們再順著這個思路想想,這個思路就是“只要去修改ListView的高度就能實現顯示其他的Item”,但是現在問題就是如何去得到一個合適的ListView的高度呢,其實最後的思路就是這樣的:“動態的測量ListView的高度然後動態的去修改ListView的高度就能實現顯示其他的Item”。

測量的大致思路如下:

就是通過ListView對象去getAdapter去得到適配器中的每個Item的然後通過一個循環遍歷地去測量每個Item的高度,然後通過累加這些Item的高度,最後得到總的高度,再把這個高度設置給ListView即可,這裡我將這個功能的實現封裝一個工具方法,只要簡單地將ListVIew對象傳入即可。

測量高度的方法:

package com.mikyou.utils;

import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ListAdapter;
import android.widget.ListView;

public class MikyouMetricListViewHeightUtils {
	public static void setListViewHeight(ListView lv){
		if (lv==null) {
			return ;
		}
		ListAdapter adapter=lv.getAdapter();
		if (adapter==null) {
			return ;
		}
		int totalHeight=0;
		for (int i = 0; i < adapter.getCount(); i++) {
			View listItem=adapter.getView(i, null, lv);
			listItem.measure(0, 0);
			totalHeight+=listItem.getMeasuredHeight();
		}
		LayoutParams params=lv.getLayoutParams();
		params.height=totalHeight+(lv.getDividerHeight()*(lv.getCount()-1));//這裡還將分割線的高度考慮進去了,統計出所有分割線占有的高度和
		lv.setLayoutParams(params);
	}
}


通過使用這個方法後直接將布局文件寫成Warp_content即可,現在不需要直接指定了明確尺寸了,看看最後的實現效果:

 

 

package com.mikyou.listviewtest;


import com.mikyou.utils.MikyouMetricListViewHeightUtils;
import com.mikyou.utils.SystemStatusManager;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView  mListView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setTranslucentStatus();
		setContentView(R.layout.activity_main);
		initData();
		initView();
	}
	private void initView() {
		mListView=(ListView) findViewById(R.id.listview);
		mListView.setAdapter(new MyAdapter());
		/**
		 * @author zhongqihong
		 * 解決ScrollView與ListView沖突的問題
		 * 該方法需要在setAdapter之後調用
		 * */
		MikyouMetricListViewHeightUtils.setListViewHeight(mListView);
		
		
		
		
		mListView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

			@Override
			public void onGlobalLayout() {
				View firstItemView=mListView.getAdapter().getView(0, null, mListView);//得到第一個Item
				firstItemView.measure(0, 0);
				System.out.println("第一個Item的高度:"+firstItemView.getMeasuredHeight());
				System.out.println("mListView的高度:"+mListView.getHeight());				
			}
		});
	}
	class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			return 7;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view=View.inflate(MainActivity.this, R.layout.home_list_item, null);
			return view;
		}

	}
	private void initData() {

	}
	private void setTranslucentStatus() {//沉浸標題欄效果
		// TODO Auto-generated method stub
		if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
			Window win=getWindow();
			WindowManager.LayoutParams winParams=win.getAttributes();
			final int bits=WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
			winParams.flags |=bits;
			win.setAttributes(winParams);
		}
		SystemStatusManager tintManager = new SystemStatusManager(this);
		tintManager.setStatusBarTintEnabled(true);
		tintManager.setStatusBarTintResource(0);
		tintManager.setNavigationBarTintEnabled(true);
	}
}

 



    

    


        

            

            

                

                    

                    

                    

                    

                    

                    
                

                
            

            
            
        
    

 

最後實現的結果:

\

\

注意:最後分析一下結果,我們可以看到我們的7個Item全部完全顯示,並且Logcat顯示的ListVIew的高度為2253px,一個Item為321px,有7個Item就是2247px,但是我們還算了分割線一個分割線占的高度為1px,7個Item占有6個分割線,所以最後的高度:2247px+6px=2253px.

OK,大功告成,以後大家可以使用我這個工具類可以方便測量ListView的高度,並且下次遇到這種問題就可以很輕松的解決了。

但是,有的人就反映說上面的方法效率不高,不過確實效率不高,因為一旦拿到的數據有很多的話,還有手動地去測量每個ListView的Item的高度,所以後來又找到兩個方法,方法一:就是通過自定一個類然後就去繼承ListView然後去重寫OnMeasure方法,然後去調用一個makeMeasureSpec方法,實際上和我們上面的方法思想一樣,因為這樣還是修改它的測量方法,還是動態測量高度從而得到真實高度,從而解決沖突。但是這個方法有一個Bug就是不能支持嵌套布局除了LinearLayout之外的類似RelativeLayout等其他布局,源碼是這樣說的:

/**
* Creates a measure specification based on the supplied size and mode.
*
* The mode must always be one of the following:
*


  • *
  • {@link android.view.View.MeasureSpec#UNSPECIFIED}

  • *
  • {@link android.view.View.MeasureSpec#EXACTLY}

  • *
  • {@link android.view.View.MeasureSpec#AT_MOST}

  • *

*
*

Note: On API level 17 and lower, makeMeasureSpec's
* implementation was such that the order of arguments did not matter
* and overflow in either value could impact the resulting MeasureSpec.
* {@link android.widget.RelativeLayout} was affected by this bug.
* Apps targeting API levels greater than 17 will get the fixed, more strict
* behavior.


*
* @param size the size of the measure specification
* @param mode the mode of the measure specification
* @return the measure specification based on size and mode
*/

 

它大致的意思:就是這個方法的作用就是通過傳入的指定的測量的尺寸和測量的模式來得到一個明確的測量方式,但是傳入的模式只支持UNSPECIFIED模式和EXACTLY模式

AT_MOST模式,並且需要注意的是在API17以及以下更低的版本中,傳入的參數的順序不重要,但是傳入的值溢出的話則會影響實際的測量,其中的相對布局就會出現這種Bug

package com.mikyou.myview;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;

public class MyListView extends ListView{

	public MyListView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public MyListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	public MyListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}
	/**
	 * 重寫OnMeasure方法
	 * onMeasure方法是測量view和它的內容,決定measured width和measured height的,
	 * 這個方法由 measure(int, int)方法喚起,子類可以覆寫onMeasure來提供更加准確和有效的測量。
          其中兩個輸入參數:
  widthMeasureSpec
  heightMeasureSpec
  分別是parent提出的水平和垂直的空間要求。
  這兩個要求是按照View.MeasureSpec類來進行編碼的。
  參見View.MeasureSpec這個類的說明:這個類包裝了從parent傳遞下來的布局要求,傳遞給這個child。
  每一個MeasureSpec代表了對寬度或者高度的一個要求。
  每一個MeasureSpec有一個尺寸(size)和一個模式(mode)構成。
  MeasureSpecs這個類提供了把一個的元組包裝進一個int型的方法,從而減少對象分配。當然也提供了逆向的解析方法,從int值中解出size和mode。
	 * 
	 * */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int expandSpec = MeasureSpec.makeMeasureSpec(  //這個makeMeasureSpec方法表示就是針對明確的測量模式,來得到相應的尺寸
				Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); //第一個參數就是傳入的尺寸size,表示Integer表示最大空間值進行2位移位運算,第二參數指定為AT_MOST表示是"warp_content"的測量模式
		super.onMeasure(widthMeasureSpec, expandSpec);//指定了我們明確的測量尺寸
	}
}



    

    

        

            

            

                

                    

                    

                    

                    

                    

                    
                

                
            


            
        
    

 

 



    

    

        

            

            

                

                    

                    

                    

                    

                    

                    
                

                
            


            
        
    

package com.mikyou.listviewtest;


import com.mikyou.myview.MyListView;
import com.mikyou.utils.MikyouMetricListViewHeightUtils;
import com.mikyou.utils.SystemStatusManager;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
	private MyListView  mListView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setTranslucentStatus();
		setContentView(R.layout.activity_main);
		initData();
		initView();
	}
	private void initView() {
		mListView=(MyListView) findViewById(R.id.listview);
		mListView.setAdapter(new MyAdapter());
		/**
		 * @author zhongqihong
		 * 解決ScrollView與ListView沖突的問題
		 * 該方法需要在setAdapter之後調用
		 * */
		//MikyouMetricListViewHeightUtils.setListViewHeight(mListView);
		
		
		
		
		mListView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

			@Override
			public void onGlobalLayout() {
				View firstItemView=mListView.getAdapter().getView(0, null, mListView);//得到第一個Item
				firstItemView.measure(0, 0);
				System.out.println("第一個Item的高度:"+firstItemView.getMeasuredHeight());
				System.out.println("mListView的高度:"+mListView.getHeight());				
			}
		});
	}
	class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			return 7;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view=View.inflate(MainActivity.this, R.layout.home_list_item, null);
			return view;
		}

	}
	private void initData() {

	}
	private void setTranslucentStatus() {//沉浸標題欄效果
		// TODO Auto-generated method stub
		if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
			Window win=getWindow();
			WindowManager.LayoutParams winParams=win.getAttributes();
			final int bits=WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
			winParams.flags |=bits;
			win.setAttributes(winParams);
		}
		SystemStatusManager tintManager = new SystemStatusManager(this);
		tintManager.setStatusBarTintEnabled(true);
		tintManager.setStatusBarTintResource(0);
		tintManager.setNavigationBarTintEnabled(true);
	}
}


運行結果和上面的一樣:

\

但是,說到這裡,我想說的是我們之前所做的努力實際上都是自己自作自受,沒事閒的蛋疼而已,實際上在真正開發中人家Goole發話了,不會在ScrollView中去放一個ListView的不信來看看Google官方的原話:

Google員工 Roman Guy早已回復:“There is no need to put a ListView in a ScrollView since ListView already supports scrolling. Do NOT put a ListView inside a ScrollView. ListView already handles scrolling, you’re only going to run into trouble. “ 更詳細的,大家可以看看他在 google i/o 上的ListView視頻講解。大家不要抱著僥幸的心理,要用正確的方法去做正確的事情。大家是不是頓時就懵逼了,是不是心中湧出一萬個草泥馬。但是如果不嵌套的話怎麼去實現這樣的一個效果呢,實際上在設計ListView的時候就可以實現對不同樣式的顯示,也就是整個界面就只用一個ListView來顯示,不搞那麼多嵌套那麼麻煩,意味我們需要用ListView中的第一個Item的位置來顯示我們其他內容,所以整體思路就出來,實際上就是通過對ListView中的position的控制,讓那些其他內容占據ListView第一個Item的位置即[position為0的位置,然後接下來其他的位置顯示真正每個Item的信息下面我們還是通過這個Demo來實現下吧:

首先我們把那些頂部其他的內容抽取成一個布局文件,然後我的主布局只有一個ListView:




    

    

        

            

            

            

            

            

            
        

        
    
    

 

主布局:



    

    
    


MainActivity

package com.mikyou.listviewtest;


import com.mikyou.myview.MyListView;
import com.mikyou.utils.MikyouMetricListViewHeightUtils;
import com.mikyou.utils.SystemStatusManager;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView  mListView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setTranslucentStatus();
		setContentView(R.layout.activity_main);
		initData();
		initView();
	}
	private void initView() {
		mListView=(ListView) findViewById(R.id.listview);
		mListView.setAdapter(new MyAdapter());
		/**
		 * @author zhongqihong
		 * 解決ScrollView與ListView沖突的問題
		 * 該方法需要在setAdapter之後調用
		 * */
		//MikyouMetricListViewHeightUtils.setListViewHeight(mListView);




		mListView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

			@Override
			public void onGlobalLayout() {
				View firstItemView=mListView.getAdapter().getView(0, null, mListView);//得到第一個Item
				firstItemView.measure(0, 0);
				System.out.println("第一個Item的高度:"+firstItemView.getMeasuredHeight());
				System.out.println("mListView的高度:"+mListView.getHeight());				
			}
		});
	}
	class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			return (1+7);//為什麼是1+7呢??因為我要把ListView的其中一個Item空間作為那些頂部內容占用,我們這是把第一個Item給它用,所以就相當於在原來基礎上添加一個Item
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

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

			if (position==0) {//如果position為0即第一項的時候,所以加載顯示頂部內容
				View view2=View.inflate(MainActivity.this, R.layout.top_listview, null);
				/**
				 * @author zhongqihong
				 * //並且要return,為什麼呢??因為我們都知道每個Item的加載出來都要去調用一次getView的方法,
				 * 所以當我已經加載出第一個Item即我們頂部內容時候,
				 * 說明getView此次加載的使命已經完成了,所以要return掉,以終止執行防止它執行接下來其他的方法
				 * */
				return view2;
			}else {//表示從第二個開始顯示正常的ListView的Item
				View view=View.inflate(MainActivity.this, R.layout.home_list_item, null);
				return view;
			}

		}

	}
	private void initData() {

	}
	private void setTranslucentStatus() {//沉浸標題欄效果
		// TODO Auto-generated method stub
		if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
			Window win=getWindow();
			WindowManager.LayoutParams winParams=win.getAttributes();
			final int bits=WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
			winParams.flags |=bits;
			win.setAttributes(winParams);
		}
		SystemStatusManager tintManager = new SystemStatusManager(this);
		tintManager.setStatusBarTintEnabled(true);
		tintManager.setStatusBarTintResource(0);
		tintManager.setNavigationBarTintEnabled(true);
	}
}


最後實現效果:

\

注意:其實最後一種方法才是最正確的最高效率的方法,根本就不需要考慮所謂嵌套沖突的問題。建議以後大家還是采用這種方法來實現。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved