Использование библиотеки ButterKnife с двумя разными представлениями в одном фрагменте

В настоящее время я пытаюсь использовать библиотеку ButterKnife для Android для обработки некоторого шаблонного кода (https://github.com/JakeWharton/butterknife)

Я настроил его, и он работает наполовину, но я столкнулся с проблемой, которую не могу решить :/

У меня есть фрагмент, который содержит 1 элемент ListView, и к этому ListView я прикрепляю представление нижнего колонтитула, содержащее несколько элементов.

Это фрагмент кода из моего фрагмента с использованием библиотеки:

public class UsersFragment extends Fragment {
    @InjectView(R.id.users_listview_id) AutoUpdatingListView list;

    private View footerView;
    @InjectView(R.id.add_user_footer_firstname_edittext_id) BootstrapEditText firstnameEditText;
    @InjectView(R.id.add_user_footer_middlename_edittext_id) BootstrapEditText middlenameEditText;
    @InjectView(R.id.add_user_footer_lastname_edittext_id) BootstrapEditText lastnameEditText;
    @InjectView(R.id.add_user_footer_cancel_button_id) BootstrapButton cancelButton;
    @InjectView(R.id.add_user_footer_okay_button_id) BootstrapButton okayButton;
    @InjectView(R.id.add_user_footer_facebook_button) BootstrapCircleThumbnail facebookButton;
    @InjectView(R.id.add_user_footer_google_plus_button) BootstrapCircleThumbnail googlePlusButton;
    @InjectView(R.id.add_user_footer_twitter_button) BootstrapCircleThumbnail twitterButton;
    @InjectView(R.id.add_user_footer_linkedin_button) BootstrapCircleThumbnail linkedInButton;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.user_fragment, container, false);
    footerView = ((LayoutInflater) getActivity().getSystemService(Activity.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.add_user_footer_view, null, false);

    ButterKnife.inject(this, rootView);

    list.setAdapter(adapter);
    }
}

Приведенный выше код НЕ работает, так как я могу вводить только 1 представление, и если я попытаюсь использовать оба из них (2x вставки), вторая вставка переопределит первую, оставив мне нулевые значения.

Кажется, я не могу указать, какое представление содержит какие элементы, как я могу с помощью обычного findViewById().

Чтобы уточнить, это мой код без ButterKnife (который работает на 100%):

    list = (AutoUpdatingListView) rootView.findViewById(R.id.users_listview_id);
    firstnameEditText = (BootstrapEditText) footerView.findViewById(R.id.add_user_footer_firstname_edittext_id);
    middlenameEditText = (BootstrapEditText) footerView.findViewById(R.id.add_user_footer_middlename_edittext_id);
    lastnameEditText = (BootstrapEditText) footerView.findViewById(R.id.add_user_footer_lastname_edittext_id);

Как вы можете видеть выше, я могу указать либо «rootView», либо «footerView» в качестве цели findViewById.

Кто-нибудь может помочь с этим вопросом? Так как это сводит меня с ума в данный момент..


person Moonbloom    schedule 23.07.2014    source источник


Ответы (1)


Простое решение состоит в том, чтобы поместить все представления нижнего колонтитула в класс-держатель представления, а затем выполнить инъекции для разных объектов, сохраняя при этом доступ к представлениям нижнего колонтитула внутри фрагмента.

@InjectView(R.id.users_listview_id) AutoUpdatingListView list;

private View footerView;
public class FooterViewHolder {
    @InjectView(R.id.add_user_footer_firstname_edittext_id) BootstrapEditText firstnameEditText;
    @InjectView(R.id.add_user_footer_middlename_edittext_id) BootstrapEditText middlenameEditText;
    @InjectView(R.id.add_user_footer_lastname_edittext_id) BootstrapEditText lastnameEditText;
    @InjectView(R.id.add_user_footer_cancel_button_id) BootstrapButton cancelButton;
    @InjectView(R.id.add_user_footer_okay_button_id) BootstrapButton okayButton;
    @InjectView(R.id.add_user_footer_facebook_button) BootstrapCircleThumbnail facebookButton;
    @InjectView(R.id.add_user_footer_google_plus_button) BootstrapCircleThumbnail googlePlusButton;
    @InjectView(R.id.add_user_footer_twitter_button) BootstrapCircleThumbnail twitterButton;
    @InjectView(R.id.add_user_footer_linkedin_button) BootstrapCircleThumbnail linkedInButton;

}
private FooterViewHolder footerViewHolder;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.user_fragment, container, false);
    footerView = inflater.inflate(R.layout.add_user_footer_view, container, false);
    footerViewHolder = new FooterViewHolder();

    ButterKnife.inject(this, rootView);
    ButterKnife.inject(footerViewHolder, footerView);

    list.setAdapter(adapter);

    return rootView;
}

Между прочим, считается плохой практикой увеличивать представления с нулевым родитель.

person Krylez    schedule 23.07.2014
comment
Великолепно! Почти работает, просто скопировав ваш код, хотя в нем было 2 небольшие ошибки. 1) ButterKnife не позволяет @InjectView внутри частного класса, поэтому пришлось сделать его общедоступным, чтобы он мог скомпилироваться 2) Я должен передать «null» в качестве корня для нижнего колонтитула, иначе я получаю «java.lang .ClassCastException: android.widget.FrameLayout$LayoutParams не может быть приведен к исключению android.widget.AbsListView$LayoutParams Большое спасибо за помощь, это было намного проще, чем я ожидал :) - person Moonbloom; 24.07.2014
comment
@Kasper, это очень плохая практика, нога будет в списке, поэтому она должна получить ее как контейнер possiblemobile.com/2013/05/layout-inflation-as-intended - person user1317422; 12.01.2015
comment
В этом примере, как бы вы затем установили, скажем, метод @OnClick для одного из представлений footerViewHolder? Или это уже невозможно? Я сделал приведенный выше код, но не смог аннотировать представление с помощью «@OnClick», поскольку оно не было найдено. - person AutoM8R; 03.12.2015
comment
@ AutoM8R Любая идея по реализации метода onclick. - person surhidamatya; 24.09.2017