Промяна на изображението ImageView в зависимост от предишния фрагмент - Viewpager

Имам CreateActivity.java, съдържащ адаптер за viewpager, който инициира два фрагмента - Fragment1.java и Fragment2.java. Във Fragment1.java имам настройка на listFragment, когато потребителят щракне върху елемент от този списък, искам да превключа изгледа към Fragment2.java и да променя съдържанието във Fragment2.java (изображение). Какво направих досега:

Във Fragment1.java задайте onClickListener за listview:

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    mCallback.onArticleSelected(position);
    ((CreateActivity) getActivity()).mViewPager.setCurrentItem(1);
}

След това се преминава към основната дейност (CreateActivity), използвайки интерфейс. След това изпрати данните за кликната позиция на Fragment2.java като пакет:

public void onArticleSelected(int position) {
    Bundle args = new Bundle();
    args.putInt(Fragment2.ARG_POSITION, position);
    Fragment2 fragobj = new Fragment2();
    fragobj.setArguments(args);
    Log.w("listposition", "" + position);
}

След това извика тази стойност във Fragment2.java чрез замяна на метода setArguments:

    @Override
    public void setArguments(Bundle args) {
    super.setArguments(args);
    int pos = args.getInt(ARG_POSITION, position);
    Log.w("myApp", "" + pos);
}

Как бих могъл сега да настроя изображението, което искам според целочислената позиция? Опитах да редактирам изгледа на изображението по този начин, но получавам NPE грешка (приложена). Някакви идеи?

@Override
public void setArguments(Bundle args) {
    super.setArguments(args);
    int pos = args.getInt(ARG_POSITION, position);
    Log.w("myApp", "" + pos);
    iv_ttx = (ImageView) getView().findViewById(R.id.iv_ttx);
    if (pos == 0){
        iv_ttx.setImageResource(R.drawable.img1);
    } else if (pos == 1){
        iv_ttx.setImageResource(R.drawable.img2);
    }
}

LogCat:

    09-03 00:32:57.053: E/AndroidRuntime(28832): FATAL EXCEPTION: main
    09-03 00:32:57.053: E/AndroidRuntime(28832): java.lang.NullPointerException
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at com.meme.hdmeme.Fragment2.setArguments(Fragment2.java:209)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at com.meme.hdmeme.CreateActivity.onArticleSelected(CreateActivity.java:44)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at com.meme.hdmeme.Fragment1.onListItemClick(Fragment1.java:65)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.support.v4.app.ListFragment$2.onItemClick(ListFragment.java:58)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.widget.AbsListView.performItemClick(AbsListView.java:1102)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2751)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.widget.AbsListView$1.run(AbsListView.java:3425)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.os.Handler.handleCallback(Handler.java:725)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.os.Handler.dispatchMessage(Handler.java:92)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.os.Looper.loop(Looper.java:137)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at android.app.ActivityThread.main(ActivityThread.java:5195)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at java.lang.reflect.Method.invokeNative(Native Method)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at java.lang.reflect.Method.invoke(Method.java:511)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
    09-03 00:32:57.053: E/AndroidRuntime(28832):    at dalvik.system.NativeStart.main(Native Method)

P.s. ред 209 е:

    iv_ttx = (ImageView) getView().findViewById(R.id.iv_ttx);

person Mustafa Nasser    schedule 02.09.2013    source източник


Отговори (2)


Fragment2 fragobj = new Fragment2();
fragobj.setArguments(args);

Проблемът с горното е, че в setArguments() се опитвате да докоснете изгледа на фрагмента, преди рамката да е имала възможност да го създаде. По принцип getView() връща null, следователно NPE.

Вместо това преместете съответния код към някой от методите на жизнения цикъл, в който съществува изгледът, т.е. onCreateView() or onActivityCreated(). Можете да получите зададените аргументи, като извикате getArguments():

@Override public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    int pos = getArguments().getInt(ARG_POSITION, position);
    Log.w("myApp", "" + pos);
    iv_ttx = (ImageView) getView().findViewById(R.id.iv_ttx);
    iv_ttx.setImageResource(pos == 0 ? R.drawable.img1 : R.drawable.img2);
}
person MH.    schedule 03.09.2013
comment
Това също не изглежда да работи, проблемът, който имам, е, че когато се поставя в onCreateView() или onActivityCreated(), получавам NPE. Това е така, защото се опитвам да върна цяло число, което не съществува, когато фрагментът е създаден. Цялото число се създава само когато потребителят кликне върху елемент в списъчен изглед. - person Mustafa Nasser; 03.09.2013
comment
Защо бихте създали фрагмента без тази целочислена стойност? Разбирам, че сте написали, че е в ViewPager, но каква е целта на това? Ако искате да покажете фрагмент B въз основа на избор във фрагмент A, тогава ViewPager не е очевиден избор. Като се има предвид това, забравете за „аргументите“, защото не можете да ги промените в движение. Един прост сетер трябва да свърши работа. Алтернативно, фрагмент B може да бъде контейнер за дъщерни фрагменти, които можете да замените въз основа на избора на потребителя. - person MH.; 03.09.2013
comment
Имам ViewPager, показващ три раздела с плъзгане, когато потребителят щракне върху изгледа на списък в първия раздел (Fragment1), бих искал той да превключи към втория раздел (Fragment2) и да покаже съответното изображение. Искам обаче потребителят също да има опцията да може да прекара пръст до втория раздел (Фрагмент2), преди да избере нещо от списъка, който се съдържа в раздела Първи (Фрагмент1). - person Mustafa Nasser; 03.09.2013

Това не се показва в съобщението за грешка, но като погледна кода, бих казал, че изключение за нулев указател също ще идва от:

iv_ttx = (ImageView) getView().findViewById(R.id.iv_ttx);

Опитвате се да получите изгледа, преди onCreateView() да бъде извикан от мениджъра на фрагменти.

Вместо да замените метода setArguments(), можете да го направите в метода onCreateView. Така:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.your_fragment_id, container, false);
    ImageView iv_ttx = view.findViewById(R.id.iv_ttx);
    int pos = getArguments().getInt(ARG_POSITION);
    if (pos == 0) {
        iv_ttx.setImageResource(R.drawable.img1);
    } else if (pos == 1){
        iv_ttx.setImageResource(R.drawable.img2);
    }
    return view;
}

Надявам се това да помогне. Може би не съм разбрал 100% въпроса.

person jeremy8883    schedule 03.09.2013
comment

Да предположим, че имам

combo(["A","B","C","D"])

Как мога да избера елемент B. Има ли свойство като selectIndex(2) или selectItem("B")?

Не можах да намеря такъв имот.

- person Mustafa Nasser; 03.09.2013