2012-06-11 26 views
6

我有ViewPagerGridView來顯示每月的日曆。 GridView有大約30個元素,左右滑動非常緩慢。我做了一個示例項目,在沒有任何數據庫訪問的情況下進行測試,速度也很慢。也許有人看到這個問題,或者我必須對頁面進行異步加載?爲什麼ViewPager和帶30個元素的GridLayout非常慢?

這是GridView中一個元素的佈局。我想在任何元素中顯示9個小小的5x5像素圖標,但是如果沒有它們,速度也會很慢。

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/Layout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="1dp"> 
    <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> 
    <TextView android:id="@+id/date" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="5dp" android:gravity="center_vertical" android:textSize="14sp" android:textStyle="bold"/> 
    </LinearLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot1" android:layout_width="wrap_content" android:drawingCacheQuality="auto" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:background="#ffffff" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:paddingBottom="1dp" android:paddingLeft="1dp" android:paddingTop="5dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="right" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="center_horizontal" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="left" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="left" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="5dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
</LinearLayout> 

這就是GridView適配器instantiateItem

public Object instantiateItem(ViewGroup container, int position) { 
    GridView gv = new GridView(m_context); 
    gv.setAdapter(new BaseAdapter() { 
     @Override 
     public View getView(int pos, View convertView, ViewGroup parent) { 
      View v; 
      if (convertView == null) { 
       // if it's not recycled, initialize some attributes 
       v = mInflater.inflate(R.layout.calendar_month_item, null); 
      } else { 
       v = convertView; 
      } 
      TextView dayView = (TextView) v.findViewById(R.id.date); 
      dayView.setText(pos + ""); 
      return v; 
     } 

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

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

     @Override 
     public int getCount() { 
      return 30; 
     } 
    }); 
    gv.setNumColumns(5); 
    ((ViewPager) container).addView(gv); 
    return gv; 
} 
+4

使用Traceview來確定瓶頸所在的位置。 – CommonsWare

+0

我看着TraceView,但我不能看到問題出在哪裏,它唯一的UI表示。 – MOST2K2

+2

你正在將你的ImageViews包裹在LinearLayout中的RelativeLayouts和TextView中:這完全沒有必要。其次,你有多個GridViews ...你有多個適配器嗎?你不需要所有的適配器。您可以在一個適配器中管理所有內容最後,考慮一下,你不需要ViewPager。通過簡單的動畫,您可以使用單個GridView工作(並且每次都重置一個適配器)。祝你好運 –

回答

5

我四處張望了一下,我想我找到你正在尋找什麼:

+0

是的,我知道這個項目。但我需要9個圖標(並且它們已啓用/禁用狀態)在gridview的一個項目中,所以我現在以編程方式添加它們。也許我把它們放在佈局中,顯示出需要的和隱藏其他的。如果使用gridview加速viewpager,我會再次發佈。 – MOST2K2

+0

我已經看過這個了,我想你應該堅持我之前說的。雖然不是在日曆的「月視圖」中顯示所有這些圖標,但如果該日包含任何圖標,則只應顯示一個圖標。然後,當您在「月視圖」中選擇日期時,將彈出當天的對話框,其中包含用戶添加到當天的所有圖標。它更容易清潔,工作速度更快。你也可以嘗試使用SQLite數據庫來存儲所有有圖標的日子以及它們包含的圖標。然後你會有很多選擇,比如'待辦事項列表'或其他。 – CommonKnowledge

+0

@ MOST2K2在我上面描述的你可以使用一個自定義的對話框,它將有它自己的XML文件。 – CommonKnowledge

2

你使用哪種版本的Android?這很重要,因爲在Android 3.0中有一個日曆,有錯誤,但不是那麼重要。

關於你的問題,如果我很好理解它。看看你的XML,它包含11個佈局,而這只是一個元素。如果你有很多,請想象一下Android系統必須完成的工作量,以充實你的所有元素。之後,當您滑動時,您可以重複使用這些元素,並且Android必須刷新那些無效的元素。這是很多工作。 (11個佈局* 30 = 330佈局將被刷新或充氣)。正如Android開發人員文檔所述,您必須始終儘可能少地使用佈局來包裝元素!

無論如何,你的方法是不正確的。我建議你查看Android 3+的CalendarView的源代碼,但給你一個提示:

創建一個星期的佈局,而不是每天(如在CalendarView中)。通過這樣做,Android將不得不刷新n個元素(您將選擇您想要顯示多少個星期),而不是30個。此佈局必須包含每天7個視圖。

希望你從中得到一些想法。

+0

我在我的三星galaxy nexus上使用Android 4.0.4。但我想運行我的應用程序的API級別> 8(2.2.x),我不使用內部日曆,它是我自己的實現。是的,這是真正的330佈局是很多工作,這是每個月。我也有一週和一天的觀點。當向左或向右滑動時,這些速度非常快。我試圖減少佈局,我希望能夠使它工作。也許我更改爲片段,並執行頁面的異步加載。 – MOST2K2

+0

如果已經存在日曆,爲什麼要發明一些東西?例如,我需要在Android日曆的每一行上繪製一些圈子。我下載了這個日曆的源代碼,並改變了一些行,並且它工作。我沒有在2.2上測試,只有3+。 – XMight

+0

我使用我的日曆作爲老師的課本,它非常具體,只有1-10個小時。 – MOST2K2

0

首先,你的佈局是有點奇怪,正如其他人說。

  • 你真的不需要架構的任何佈局子元素。
  • 在不需要時有多個嵌套的相對或線性佈局將非常昂貴,尤其是在包裝在ViewPager中的GridView中時。

其次,ViewPager和PagerAdapter有點棘手。

  • 當您有默認的離屏頁面數量時,您將同時佈置所有三個頁面。如果你把它設得更高,你將會佈置更多的觀點。
  • 請確保您正確刪除destroyItem中的視圖。
  • 正確實施isViewFromObject方法,因爲否則當您翻頁時您的視圖將被丟棄,導致重新創建它們的成本更高。

去@ CommonsWare的建議可能是一個好主意。 TraceView有點難以使用,但即使如此,它可能會產生一些線索。

+0

是的,這是真的,我不需要這樣的子元素。我不更改3的默認屏幕外頁面。remove和isViewFromObject已正確實施。 – MOST2K2

相關問題