添加片段时,Android注释@afterviews会多次调用

时间:2014-08-06 22:27:54

标签: android-fragments android-annotations

我有一个片段,无论何时将它添加到布局,都会调用@afterviews。

因此,例如在父活动中,我检查片段是否已经创建,如果没有给它充气。然后我检查片段是否已添加到布局中,如果没有添加它并显示新片段

@Click(R.id.tvActionFriends)
void friendsClicked() {

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    if (friendsFragment == null) {
        friendsFragment = new FriendsFragment_();

    }

    if (!friendsFragment.isAdded()) {
        app.log("not added adding fragment");
        fragmentTransaction.add(R.id.layoutMainContainer, friendsFragment);
    }

    fragmentTransaction.show(friendsFragment);
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();

}

第一次点击它通常会经历生命周期。

所以现在用户按下后退按钮我可以看到拆卸onPause()onDestroy()和onDetach()

所以现在从布局中删除了friendsFragment,但该类仍然存在。

现在,用户再次单击按钮以在主机活动中显示friendsFragment。这次片段已经存在但不在布局中,因此重新添加并提交事务

现在片段经历了创建的生命周期,但是@afterviews方法被触发两次,如果用户再次点击并且第三次点击按钮@seviews将被触发3次等...

这是friendsFragment

@EFragment(R.layout.fragment_friends)
public class FriendsFragment extends BaseFragment {

ArrayList<String> numbers, facebookIds, emails;
ArrayList<Friend> friends;

@Bean
FriendsAdapter friendsAdapter;

@ViewById(R.id.lvFriends)
CustomListView lvFriends;

boolean gettingFriends = false;

@AfterInject
void initInject() {
    super.baseInject();

    numbers = new ArrayList<String>();
    facebookIds = new ArrayList<String>();

    friends = new ArrayList<Friend>();
    friendsAdapter.setItems(friends);
}

@AfterViews
void initViews() {
    super.baseViews();

    lvFriends.setAdapter(friendsAdapter);

    Cursor phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null, null, null, null);
    while (phones.moveToNext()) {
        String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String phoneNumber = phones.getString(phones
                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER));

        if (phoneNumber != null) {

            phoneNumber = phoneNumber.replace("+", "");

            numbers.add(phoneNumber);

        }
    }
    phones.close();

    getFriends();

}

OnFriendsListener onFriendsListener = new OnFriendsListener() {
    @Override
    public void onComplete(List<Profile> friends) {
        for (Profile p : friends) {
            app.log(p.getName());
        }
    }

    @Override
    public void onException(Throwable throwable) {
        app.log(throwable.getMessage());
    };

    @Override
    public void onFail(String reason) {
        app.log(reason);
    }
};

@Background
void getFriends() {

    if (gettingFriends == true)
        return;

    gettingFriends = true;

    friends.clear();

    MultiValueMap<String, String> data = new LinkedMultiValueMap<String, String>();

    data.add("numbers", numbers.toString());
    data.add("facebook_ids", facebookIds.toString());

    ArrayList<Friend> resp = snapClient.recommendFriends(data);

    friendsCallback(resp);

}

@UiThread
void friendsCallback(ArrayList<Friend> resp) {

    if (resp != null)
        friends.addAll(resp);
    friendsAdapter.notifyDataSetChanged();

    gettingFriends = false;
}

}

正如您所看到的,片段扩展了一个basefragment并调用了父super.baseInject()和super.baseViews()来处理所有片段中的公共类字段

基本片段看起来像这样,它基本上只是注入几个类并记录片段的活动生命周期

@EFragment
public class BaseFragment extends Fragment {

@App
MyApp app;

@SystemService
LayoutInflater layoutInflater;

@Bean
VideoCache videoCache;

@RestService
CloudClient cloudClient;

@Bean
MyResources myResources;

@ViewById(R.id.tvActionExtra)
TextView tvActionExtra;

SnapClient snapClient;

FragmentManager fragmentManager;

SimpleFacebook simpleFacebook;

void baseInject() {

    app.log("init inject " + this.getClass().getCanonicalName());

    app.currentContext = getActivity();
    snapClient = app.snapClient;



}



void baseViews() {
    app.log("init views " + this.getClass().getCanonicalName());
}

@Override
public void onAttach(Activity activity) {
    Log.d(MyApp.TAG,"attach " + this.getClass().getCanonicalName());
    super.onAttach(activity);

    if (activity instanceof MainActivity) {
        try {
            MainActivity a = (MainActivity) activity;
            simpleFacebook = a.simpleFacebook;


        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
void toast(String message) {
    app.toast(message);
}

AlertDialog simpleAlert(String title, String message) {
    return MyApp.simpleAlert(getActivity(), title, message);
}


@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    Log.d(MyApp.TAG,"create " + this.getClass().getCanonicalName());
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.d(MyApp.TAG,"create view " + this.getClass().getCanonicalName());
    return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onPause() {
    Log.d(MyApp.TAG,"pause" + this.getClass().getCanonicalName());;
    super.onPause();
}

@Override
public void onResume() {
    Log.d(MyApp.TAG,"resume " + this.getClass().getCanonicalName());
    super.onResume();
}


@Override
public void onDetach() {
    Log.d(MyApp.TAG,"detach " + this.getClass().getCanonicalName());
    super.onDetach();
}

@Override
public void onDestroy() {
    Log.d(MyApp.TAG,"destroy " + this.getClass().getCanonicalName());
    super.onDestroy();
}

}

我不会&#39;知道如果它是一个机器人注释的东西我搞砸了或片段的东西,任何帮助是值得赞赏的。

1 个答案:

答案 0 :(得分:0)

看起来这可以在AndroidAnnotations 3.3中修复?

根据https://github.com/excilys/androidannotations/pull/1275上的问题,https://github.com/excilys/androidannotations/issues/1264发出拉取请求。