2012-12-29 171 views
0

我正在開發測試以嘗試瞭解視圖和視圖組的行爲。我創建了一個非常簡單的自定義視圖組(以下稱爲viewgroup1),我正確實現了所有重要的方法(onLayout,onMeasure,onSizeChanged)。然後我創建了一個簡單的視圖,並將該視圖從onclick事件添加到viewgroup1。該視圖顯示正確,並調用其方法(onSizeChanged,onLayout,onDraw)。自定義視圖不會繪製在自定義視圖組中

在成功測試之後,我創建了另一個自定義視圖組(此後稱爲viewgroup2),並且這次我已將viewgroup2添加到viewgroup1。然後我已將自定義視圖添加到onclick事件的viewgroup2中。我預計所有事情都會在第一個測試中發生,但是當我點擊viewgroup2時,視圖會被添加到這個視圖中,但是隻有viewgroup1方法被調用(onMeasure,onLayout)。調用不會沿着繼承樹傳播。

結果是樹結構是正確的,但儘管我已經爲每個對象調用了requestLayout,forcelayout等等,但並未顯示視圖。

樹的結構是:viewgroup1 --- viewgroup2 --- view。

清單的代碼:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.yoredevelopment.tests" 
    android:versionCode="1" 
    android:versionName="1.0" > 
    <uses-sdk android:minSdkVersion="11" /> 
    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".AndroidTestsActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 
</manifest> 

佈局代碼(main.xml中):

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:custom="http://schemas.android.com/apk/res/com.yoredevelopment.tests" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#ff000000" 
    android:orientation="vertical" > 
     <com.yoredevelopment.tests.TestViewGroup 
       android:id="@+id/TestViewGroup" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:background="#ff00cccc" 
       /> 
</LinearLayout> 

活動碼:

import android.app.Activity; 
import android.os.Bundle; 

public class AndroidTestsActivity extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 
} 

查看和ViewGroups代碼:

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.ViewGroup; 

public class TestViewGroup extends ViewGroup { 
    public TestViewGroup(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     TestViewChild tvc = new TestViewChild(context); 
     tvc.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 
     tvc.setBackgroundColor(Color.WHITE); 
     this.addView(tvc); 
    } 

    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     if(this.getChildCount() > 0) { 
      View child = this.getChildAt(0); 
      View p = (View)this.getParent(); 
      child.layout(20, 20, p.getWidth() - 40, p.getHeight() - 40); 
     } 
    } 

    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
    } 

    class TestViewChild extends ViewGroup { 
     public TestViewChild(Context context) { 
      super(context); 
      this.setOnClickListener(new TestClickListener()); 
     } 

     protected void onLayout(boolean changed, int l, int t, int r, int b) { 
      if(this.getChildCount() > 0) { 
       View child = this.getChildAt(0); 
       child.layout(10, 10, 40, 40); 
      } 
     } 

     protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
      super.onSizeChanged(w, h, oldw, oldh); 
     } 
    } 

    class TestView extends View { 
     private Paint p; 
     public TestView(Context context) { 
      super(context); 
      p = new Paint(); 
      p.setColor(Color.RED); 
      p.setStyle(Style.FILL); 
     } 

     protected void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 
      int centerX = this.getWidth()/2; 
      int centerY = this.getHeight()/2; 
      canvas.drawCircle(centerX, centerY, 5, this.p); 
     } 

     protected void onLayout(boolean changed, int l, int t, int r, int b) { 
      super.onLayout(changed, l, t, r, b); 
     } 

     protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
      super.onSizeChanged(w, h, oldw, oldh); 
     } 
    } 

    class TestClickListener implements OnClickListener { 
     public void onClick(View v) { 
      ViewGroup vg = (ViewGroup)v; 
      TestView tv = new TestView(vg.getContext()); 
      tv.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 
      tv.setBackgroundColor(Color.GREEN); 
      vg.addView(tv); 
      tv.bringToFront(); 
     } 
    } 
} 

如果我在ViewGroup2構造函數中創建視圖,則會顯示該視圖,但在從onclick事件創建視圖時不會發生該視圖。

在此先感謝,並有一個愉快的假期。

回答

0

兩個萬物春從源代碼介意:

對於任何意見的

1 /還沒有提供您的LayoutParams - 添加視圖作爲一個孩子的時候,你應該使用它們。

2 /您的onMeasure代碼在所有三種情況下都不正確。你使用超級來做測量,然後從規格(可能是0)中獲得尺寸並覆蓋超級測量的尺寸。全部刪除它們讓超級處理它們。

+0

感謝您的回答。我已將代碼添加到我的文章中,並希望您能幫助我。 我已經使用顏色,並且兩個視圖組都顯示正確。 – user1930133

+0

我在看到源代碼後更改了我的答案。 – nmw

+0

再次感謝。 OnMeasure方法被實現來放置它們的日誌來檢查維度不是0.我已經刪除了onMeasure方法,並且我爲每個視圖提供了LayoutParams,但行爲是相同的。您可以看到上面的更改(我已根據您的建議更改了代碼) – user1930133