0

I want to build reusable widget. It should be ordinal composite of standard elements. What is the best approach. Below is the code sample which I use currently, however there might be something more elegant. Furthermore the sample below runs perfectly in runtime, but visual editor in Eclipse is throwing exceptions (which is not a problem for me at this time). Is there any recommended way of creating composites? Should I use fragment?

public class MyComposite extends LinearLayout {

  private ImageView m_a1;
  private ImageView m_a2;
  private ImageView m_w1;
  private ImageView m_w2;
  private ImageView m_w3;
  private ImageView m_w4;

  public CallBackSlider(final Context context) {
    this(context, null);
  }

  public CallBackSlider(final Context context, final AttributeSet attrs) {
    super(context, attrs);

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

  private void setupViewItems() {
    m_a1 = (ImageView) findViewById(R.id.A1Img);
    m_w1 = (ImageView) findViewById(R.id.Wave1Img);
    m_w2 = (ImageView) findViewById(R.id.Wave2Img);
    m_w3 = (ImageView) findViewById(R.id.Wave3Img);
    m_w4 = (ImageView) findViewById(R.id.Wave4Img);
    m_a2 = (ImageView) findViewById(R.id.A2Img);
    resetView();
  }

  private void resetView() {
    m_w1.setAlpha(0);
    m_w2.setAlpha(0);
    m_w3.setAlpha(0);
    m_w4.setAlpha(0);
  }
}

Layout xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/MyComposite"
  ...  >

  <ImageView
    android:id="@+id/A1Img"
    android:src="@drawable/a1"
    ...
   />

  <ImageView
    android:id="@+id/Wave1Img"
    ...
    android:src="@drawable/wave1" />

  <ImageView
    android:id="@+id/Wave2Img"
    ...
    android:src="@drawable/wave2" />

  <ImageView
    android:id="@+id/Wave3Img"
    ...
    android:src="@drawable/wave3" />

  <ImageView
    android:id="@+id/Wave4Img"
    ...
    android:src="@drawable/wave4" />

<ImageView
    android:id="@+id/EarImg"
    ...
    android:src="@drawable/a2" />

</LinearLayout>

Then you can use it in other layouts like this:

...
<your.package.MyComposite 
    android:id="@+id/mc1"
    ...       
/>
...

And use from java code as well as instance of MyComposite class.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Aleksander Gralak
  • 1,509
  • 10
  • 26

2 Answers2

1

In your example i think you need merged widgeds.

If you need to change standart behaviour of your widget customize it then use you custom widget.

But if you need group of view with standart behavior, it is enough to merge them.

some_activity.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical">

    // some views

    <include layout="@layout/view_part"/>

   // probably more views

</LinearLayout>

view_part.xml:

    <merge xmlns:android="http://schemas.android.com/apk/res/android">

       <ImageView
       android:id="@+id/A1Img" 
       android:src="@drawable/a1"
       ...
       /> 

       <ImageView
       android:id="@+id/Wave1Img"
       ...
       android:src="@drawable/wave1" />

       <ImageView
       android:id="@+id/Wave2Img"
       ...
       android:src="@drawable/wave2" />

       <ImageView
       android:id="@+id/Wave3Img"
       ...
       android:src="@drawable/wave3" />

       <ImageView
       android:id="@+id/Wave4Img"
       ...
       android:src="@drawable/wave4" />

       <ImageView
       android:id="@+id/EarImg"
       ...
       android:src="@drawable/a2" />       

    </merge>
Talha
  • 12,673
  • 5
  • 49
  • 68
  • I am googling to find what is a merged widget. Can you point me to some good explanation? Why it is good and when should be used. – Aleksander Gralak Dec 10 '12 at 10:43
  • For example,you need a button always create an Toast message when clicked, or you need a gallery which will have a different swipe animation. So in this situation you can extend gallery or button to create your custom view to use it easily in yor activity. But in your question you need a group of widget with standat behavior. So you need to merge them and use it in your activity. – Talha Dec 10 '12 at 10:51
1

Recently the nested fragments were introduced (in SDK 4.1 or 4.2 and in the compat library). But I would tend to think one should use these nested fragments to encapsulate more complex pieces of UI than just a simple widget like yours.

The usual approach for custom widgets is to override the onFinishInflate method. You have a tutorial on that blog.

Here is the corresponding piece of code:

public class TwoTextWidget extends LinearLayout {
    private TextView textOne;
    private TextView textTwo;

    public TwoTextWidget(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        ((Activity)getContext()).getLayoutInflater().inflate(R.layout.two_text_component, this);
        setupViewItems();
    }

    private void setupViewItems() {
        textOne = (TextView) findViewById(R.id.text_one);
        textTwo = (TextView) findViewById(R.id.text_two);
    }

    public void setTextOne(String text) {
        textOne.setText(text);
    }

    public void setTextTwo(String text) {
        textTwo.setText(text);
    }
}

You could allow more customisation of your widget using custom attributes. Check out that other blog.

Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
  • I have ready both blogs you mentioned. I had some problem with the samlpe code which overrides onFinishInflate(). It this a recommended way or just someone idea? I also knew about custom attributes: http://stackoverflow.com/questions/5706038/long-press-definition-at-xml-layout-like-androidonclick-does/13417824#13417824 – Aleksander Gralak Dec 10 '12 at 10:41
  • Then you know all you need I guess :) I never had any issue with onFinishInflate. That's the approach I saw most of the time. You can try to browse a few OpenSource widgets to see how they did it. – Vincent Mimoun-Prat Dec 10 '12 at 10:44