2012-12-29 125 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