Arun Badole
Arun Badole

Reputation: 11097

How to add a custom view in another custom view in Android?

I want to create a custom view which should be added in another custom view.

The second view will be a container, so it should be able to contain the first view as its child.

For creating this views I am extending ViewGroup & LinearLayout classes.

Child view class is NodeView

public class NodeView extends LinearLayout
{
    private final static String TAG = "NodeView";
    private ImageView ivTop;
    private ImageView ivBottom;
    private Context myContext;

    public NodeView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.myContext = context;

        setOrientation(LinearLayout.VERTICAL);
        setGravity(Gravity.CENTER);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.view_test_multi, this, true);

        ivTop = (ImageView) getChildAt(0);
        ivBottom = (ImageView) getChildAt(2);

        ivTop.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Toast.makeText(myContext, "Top Clicked", Toast.LENGTH_SHORT).show();
            }
        });

        ivBottom.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Toast.makeText(myContext, "Bottom Clicked", Toast.LENGTH_SHORT).show();
            }
        });

    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
    }

    public NodeView(Context context)
    {
        this(context, null);
    }
}

& the container class is TreeViewGroup

public class TreeViewGroup extends ViewGroup
{
private static final String TAG = "CustomTreeNodeView";

NodeView nodeView;

public TreeViewGroup(Context context, AttributeSet attrs, int defStyleAttr)
{
    super(context, attrs, defStyleAttr);
    nodeView = new NodeView(getContext());
    addView(nodeView);
}

public TreeViewGroup(Context context, AttributeSet attrs)
{
    this(context, attrs, 0);
}

public TreeViewGroup(Context context)
{
    this(context, null, 0);
}

@Override
protected void onDraw(Canvas canvas)
{
    super.onDraw(canvas);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
  }
}

& xml layout for node view is view_test_multi.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >


    <ImageView
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_centerVertical="true"
        android:src="@drawable/point_grey" />

    <ImageView
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_centerVertical="true"
        android:src="@drawable/point_red" />

    <ImageView
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_centerVertical="true"
        android:src="@drawable/point_grey" />

</merge>

My activity's layout is activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res/com.ab1209.testcustom"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <com.ab1209.testcustom.view.TreeViewGroup
        android:id="@+id/activity_main_custom_tree_node_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

MainActivity class is

**public class MainActivity extends Activity
{

    TreeViewGroup treeNodeView;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        treeNodeView = (TreeViewGroup) findViewById(R.id.activity_main_custom_tree_node_view);
    }

}**

When I run the app I don't see the NodeView added in main View. Am I doing the right thing if not please tell me how can I make it working?

Upvotes: 0

Views: 994

Answers (1)

Krish
Krish

Reputation: 3885

To create a custom ViewGroup, the only method you need to override is onLayout. The onLayout is triggered after the ViewGroup itself has finished laying itself out inside its own container ViewGroup and is now responsible for laying out its children. It should call the layout method on all of its children to now position and size them (the left and top parameters will determine the child view’s x and y and the right and bottom will determine its width (right – left) and height (top-bottom).

So your TreeViewGroup code will look like :

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) {

                ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) child
                        .getLayoutParams();

                int childLeft = 0;
                int childTop = 0;
                child.layout(childLeft, childTop,
                        childLeft + child.getMeasuredWidth(),
                        childTop + child.getMeasuredHeight());

            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        int measuredWidth = 200; // Calculate the height
        int measuredHeight = 200; // Calculate the width

        setMeasuredDimension(measuredWidth, measuredHeight);
    }

Refer this link http://arpitonline.com/2012/07/01/creating-custom-layouts-for-android/

Upvotes: 1

Related Questions