Question

I got a custom component (something like information panel) - LinearLayout with few of textviews. I am using android annotations.

PROBLEMS
If i try to use @AfterViews, that method is never called (problem 1).
Problem is when i try to set something in the textview through annotations, that textview is null (problem 2)..

If i try that from another class, where i am sure android annotations works, i can easy and without any problem get on that textView and set there something..The variable is not null and there are no problems..BUT in another classes where i use AA, i use Activity as well..:/ so i am thinking if there is problem in @EViewGroup.. But according to their javadoc, @EVIewGroup has no problem with AfterViews and ViewById..(according to their sites, fast everything is viewGroup :] and i think i select the right possibility for extending from linearLayout)

Does someone have some tip what i am missing?

-- I use that custom component in one more fragments.
-- There is one class calling method in this class (--> in code preview -- somethingIsCalling()), and that method is fired when something want to display in the textView)

Problem code:

Custom component layout (info_panel.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:baselineAligned="false"
    android:id="@+id/infoPanel">
    <TextView
        android:id="@+id/txtAccName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="right|center_vertical" />
</LinearLayout>

java code for that custom component:

@EViewGroup(R.layout.info_panel)
public class InfoPanel extends LinearLayout {
    @ViewById(R.id.txtAccName)
    protected TextView txtName;

        public InfoPanel(Context ctx, AttributeSet attr)
    {
        super(ctx, attr);
        LayoutInflater.from(ctx).inflate(R.layout.info_panel, this);
    }

    @AfterViews
    protected void init() 
    {
            // PROBLEM 1, THIS METHOD IS NEVER CALLING
        txtName.setText("call after view");
    }

    public void somethingIsCalling()
    {
            // PROBLEM 2, txtName WHEN ITS CALLED IS NULL
            txtName.setText("something is calling");
    }
}
Was it helpful?

Solution

Here is how I would rewrite your code to get it work:

layout_info_panel.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
        android:id="@+id/txtAccName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="right|center_vertical" />
</merge>

Note how you can replace root <LinearLayout/> with <merge/> here but still be able to use all <LinearLayout/> specific attributes (e.g. layout_weight="1") (https://github.com/excilys/androidannotations/wiki/Enhance-custom-views#how-to-create-it-)
It is possible because your custom class InfoPanel extends LinearLayout.
As a bonus you can remove 1 level of hierarchy, which is always small performance boost (http://www.curious-creature.org/2012/12/01/android-performance-case-study/)

InfoPanel.java

@EViewGroup(R.layout.info_panel)
public class InfoPanel extends LinearLayout {
    @ViewById(R.id.txtAccName)
    protected TextView txtName;

    public InfoPanel(Context ctx, AttributeSet attr) {
        super(ctx, attr);
        // remove this inflation, AndroidAnnotations does this for you in @EViewGroup(R.layout.info_panel)
        // LayoutInflater.from(ctx).inflate(R.layout.info_panel, this);
    }

    @AfterViews
    protected void init() {
            // PROBLEM 1 would be fine now
        txtName.setText("call after view");
    }

    public void somethingIsCalling() {
            // PROBLEM 2 also will be resolved IF you call it after @AfterViews method has done binding.
            txtName.setText("something is calling");
    }
}

Now wherever you want to include your InfoPanel in xml, MAKE SURE to include generated class (one with _underscore), otherwise your fields will indeed always be null, i.e.

EDIT: apparently in this case this was causing issues for OP and changing <com.stackoverflow.answers.InfoPanel> to <com.stackoverflow.answers.InfoPanel_> solved fields being null.

layout_ordinary_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <com.stackoverflow.answers.InfoPanel_
        android:id="@+id/infoPanelView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    …
</LinearLayout>

(https://github.com/excilys/androidannotations/wiki/Enhance-custom-views#how-to-use-it-)
I advise you to go through all Cookbook in AndroidAnnotations wiki, there are couple of more common pitfalls over there.

OTHER TIPS

try to remove the argument from @EViewGroup, it has solved a simiilar problem for me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top