Android: обновить фрагмент с динамическим списком с помощью ViewPager и ActionbarTab

#android #android-fragments #android-asynctask #android-actionbar #android-viewpager

#Android #android-фрагменты #android-asynctask #android-панель действий #android-viewpager

Вопрос:

Я совсем новичок в Android. Я застрял с этой проблемой уже несколько дней. Я использую новый шаблон вкладки панели действий Google с помощью салфетки (ViewPager). Внутри каждого фрагмента я хочу отобразить динамический список карточек (с помощью cardslib: https://github.com/gabrielemariotti/cardslib ). Данные для карточек поступают из AsyncTask, который извлекает данные из URL.

Это моя проблема: когда я запускаю приложение, отображается первое представление, но ViewPager подготавливает представление для второй страницы, поэтому асинхронная задача для второго экрана тоже запускается. И карты второго экрана добавляются к первому. Затем, если я проведу пальцем по второму экрану, ничего не отобразится, и будет запущена асинхронная задача для третьего экрана. Итак, если провести пальцем по третьему экрану, ничего… А затем, если я снова переключусь на второй экран, отобразятся карточки с данными первого экрана… Настоящий беспорядок!

Я думаю, что у меня проблема с onCreate, onCreateView или что-то в этом роде. Возможно, код иногда находится не в нужном месте.. Я не знаю. Я перепробовал множество небольших модификаций, но ничего не получилось. (но это работало так только с вкладкой панели действий и без ViewPager).

Спасибо

Вот мой код :

 import java.util.Locale;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v13.app.FragmentPagerAdapter;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
/**
 * The {@link android.support.v4.view.PagerAdapter} that will provide
 * fragments for each of the sections. We use a {@link FragmentPagerAdapter}
 * derivative, which will keep every loaded fragment in memory. If this
 * becomes too memory intensive, it may be best to switch to a
 * {@link android.support.v13.app.FragmentStatePagerAdapter}.
 */
SectionsPagerAdapter mSectionsPagerAdapter;

/**
 * The {@link ViewPager} that will host the section contents.
 */
ViewPager mViewPager;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set up the action bar.
    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    mSectionsPagerAdapter.notifyDataSetChanged();

    // When swiping between different sections, select the corresponding
    // tab. We can also use ActionBar.Tab#select() to do this if we have
    // a reference to the Tab.
    mViewPager
            .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                    actionBar.setSelectedNavigationItem(position);


//mSectionsPagerAdapter.notifyDataSetChanged();


                }
            });

    // For each of the sections in the app, add a tab to the action bar.
    for (int i = 0; i < mSectionsPagerAdapter.getCount(); i  ) {
        // Create a tab with text corresponding to the page title defined by
        // the adapter. Also specify this Activity object, which implements
        // the TabListener interface, as the callback (listener) for when
        // this tab is selected.
        actionBar.addTab(actionBar.newTab()
                .setText(mSectionsPagerAdapter.getPageTitle(i))
                .setTabListener(this));
    }
    mSectionsPagerAdapter.notifyDataSetChanged();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onTabSelected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
    // When the given tab is selected, switch to the corresponding page in
    // the ViewPager.
    if(tab.getPosition() != mViewPager.getCurrentItem()) {
        mViewPager.setCurrentItem(tab.getPosition());
    }
//      mViewPager.setCurrentItem(tab.getPosition());

}

@Override
public void onTabUnselected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
    mSectionsPagerAdapter.notifyDataSetChanged();

}

@Override
public void onTabReselected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
    mSectionsPagerAdapter.notifyDataSetChanged();

}

/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
//           getItem is called to instantiate the fragment for the given page.

        return PlaceholderFragment.newInstance(position   1);


    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }



    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();
        switch (position) {
        case 0:
            return getString(R.string.title_section1).toUpperCase(l);
        case 1:
            return getString(R.string.title_section2).toUpperCase(l);
        case 2:
            return getString(R.string.title_section3).toUpperCase(l);
        }
        return null;
    }
}

}
  

И вот фрагмент

 import it.gmariotti.cardslib.library.internal.Card;
import it.gmariotti.cardslib.library.internal.CardArrayAdapter;
import it.gmariotti.cardslib.library.internal.CardHeader;
import it.gmariotti.cardslib.library.view.CardListView;

import java.util.ArrayList;
import java.util.List;

import android.app.Fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.example.webanajones.asyncTask.GetItemTask;
import com.example.webanajones.asyncTask.IResultsListener;
import com.example.webanajones.asyncTaskResponse.ItemJsonResponse;
import com.example.webanajones.asyncTaskResponse.ItemJsonResponse.Item;

/**
 * A placeholder fragment containing a simple view.
 */
public class PlaceholderFragment extends Fragment implements
        IResultsListener {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */
    static final String ARG_SECTION_NUMBER = "section_number";
    public static int limit = 0;
    IResultsListener listener = this;
    ArrayList<Card> cards = new ArrayList<Card>();
    CardArrayAdapter mCardArrayAdapter;
    int flag = 0;
    boolean loadMore = true;
    CardListView listView;
    private int idx;


    @Override
    public void onCreate(Bundle savedInstanceState) {       
        super.onCreate(savedInstanceState);
//      Bundle data = getArguments();
//      idx = data.getInt("idx")  1;

        limit = 0;
        flag = 0;
        loadMore = true;

        List<String> params = new ArrayList();
        params.add(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));

        params.add(String.valueOf(limit));
        GetItemTask getItemTask = new GetItemTask();
        getItemTask.setOnResultsListener(listener);
        getItemTask.execute(params);

    }


    /**
     * Returns a new instance of this fragment for the given section number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public PlaceholderFragment() {
    }

    @SuppressWarnings("unchecked")
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);

        return rootView;

    }

    @Override
    public void onGetItemTaskSucceeded(ItemJsonResponse itemJsonResponse) {
        if (mCardArrayAdapter != null) {
            mCardArrayAdapter.notifyDataSetChanged(); 

        }

        if (itemJsonResponse.getSuccess() != 0) {

            loadMore = true;
            final Item[] itemTable = itemJsonResponse.getItemArray();

            for (int itemIndex = 0; itemIndex < itemTable.length; itemIndex  ) {

                if (itemTable[itemIndex].getTypeId() == 2) { // 2 = type GIF
                    final int index = itemIndex;
                    Card gifCard = new CardGif(getActivity()){


                        @Override
                        public void setupInnerViewElements(ViewGroup parent, View view) {
                            DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
                            int width = (int) (metrics.widthPixels * 0.97);
                            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.WRAP_CONTENT);
                            params.bottomMargin = 30;
                            LinearLayout LinearLayout = (LinearLayout) parent.findViewById(R.id.inner_frame);

                            GIFWebView gifView = new GIFWebView (getActivity(), itemTable[index].getObjectUrl());

                            LinearLayout.addView(gifView);


                        }
                    }; 
                    CardHeader header = new CardHeader(getActivity());
                    header.setTitle(itemTable[itemIndex].getTitle());
                    cards.add(gifCard);
                }

                if (itemTable[itemIndex].getTypeId() == 1) { // 1 = image
                    Card card = new Card(getActivity());
                    CardHeader header = new CardHeader(getActivity());
                    header.setTitle(itemTable[itemIndex].getTitle());
                    card.addCardHeader(header);
                    MyThumbnail thumb = new MyThumbnail(getActivity(), itemTable[itemIndex].getObjectUrl());
                    thumb.setExternalUsage(true);

                    card.addCardThumbnail(thumb);
                    final int index = itemIndex;
                    card.addPartialOnClickListener(Card.CLICK_LISTENER_THUMBNAIL_VIEW, new Card.OnCardClickListener() {
                        @Override
                        public void onClick(Card card, View view) {
                            Intent intent = new Intent(getActivity(), FullscreenActivity.class);
                            intent.putExtra("imageUrl", itemTable[index].getObjectUrl());
                            startActivity(intent);
                        }
                    });
                    cards.add(card);
                }

            }
            if (flag == 0) {
                mCardArrayAdapter = new CardArrayAdapter(getActivity(), cards);
                listView = (CardListView) getActivity().findViewById(
                        R.id.carddemo_list);
                listView.setAdapter(mCardArrayAdapter);

                flag = 1;
            }               
        } 
        else {
            loadMore = false;
        }
        loadMoreCards(mCardArrayAdapter, loadMore);

    }

    public void loadMoreCards(CardArrayAdapter mCardArrayAdapter, boolean loadMore) {


        if (listView != null) {
            mCardArrayAdapter.notifyDataSetChanged(); 

            if (loadMore) {
                listView.setOnScrollListener(new EndlessScrollListener() {

                    @Override
                    public void onLoadMore(int page, int totalItemsCount) {
                        limit  = 5;
                        List<String> params = new ArrayList();
                        params.add("1");
                        params.add(String.valueOf(limit));          
                        GetItemTask getItemTask = new GetItemTask();
                        getItemTask.setOnResultsListener(listener);
                        getItemTask.execute(params);


                    }
                });
            }

        }
    }
//fin placeholderfrag

    @Override
    public void onGetImageTaskSucceeded(Bitmap bitmap) {
        // TODO Auto-generated method stub

    }
}
  

Комментарии:

1. Взгляните here:github.com/gabrielemariotti/cardslib/issues/85

Ответ №1:

Спасибо @GabrieleMariotti, это помогло! На самом деле я уже пытался использовать разные классы для разных фрагментов, но я забываю указывать разные идентификаторы в своих списках карточек. Это решило проблему. Кстати, хорошая работа для вашей библиотеки, это потрясающе.

Итак, для следующего: создайте разные классы для всех ваших разных фрагментов. Они должны использовать другой макет, а cardsList должен использовать другой идентификатор.