ViewPager ve parçaları — 'parçasını saklamak için doğru yol ne s'in devlet?
Parçaları bazı modüllere UI mantık ayrımı için çok güzel gibi duruyor. Ama ViewPager
birlikte ömrü benim için hala puslu. Guru düşünceler çok gerekli!
Edit
Aptal çözüm aşağıda ;-)
Kapsam
Ana faaliyet parçaları ile ViewPager
vardır. Bu parçalar biraz (submain) faaliyetleri, parçaları diğer mantık' veri aktivite içinde geri arama arayüzü ile doldurulur. farklı uygulamak Ve her şey ilk fırlatma ama! gayet iyi çalışıyor...
Sorun
Etkinlik yapmak ViewPager
'In parçaları. bu yüzden yeniden (yönünü değiştirmek vb.) alır Kod (da bulacaksınız aşağıda) diyor her zaman faaliyettir oluşturulan çalışıyorum oluşturmak için yeni ViewPager
adaptör parçaları ile aynı parçaları (belki de sorun bu.) ama FragmentManager zaten tüm bu parçalar saklı bir yerde (nerede?) ve başlar bu eğlence mekanizması. Eğlence mekanizması "eski" parçanın onAttach, onCreateView, vb. aramalar çok benim geri arama arayüzü Etkinlik uygulanan yöntem ile veri başlatmak için arayın. Ama bu yöntem Aktivitenin onCreate yöntemi ile oluşturulan yeni oluşturulan bir parçasına işaret eder.
Sorun
Belki yanlış ama desen bile 3 Pro Android kitap hakkında pek bir şey yok kullanıyorum. Yanilütfenbana bir-iki yumruk vermek ve bunu doğru şekilde yapmak için nasıl. Çok teşekkürler!
Kod
Ana Faaliyet
public class DashboardActivity extends BasePagerActivity implements OnMessageListActionListener {
private MessagesFragment mMessagesFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
Logger.d("Dash onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_container);
new DefaultToolbar(this);
// create fragments to use
mMessagesFragment = new MessagesFragment();
mStreamsFragment = new StreamsFragment();
// set titles and fragments for view pager
Map<String, Fragment> screens = new LinkedHashMap<String, Fragment>();
screens.put(getApplicationContext().getString(R.string.dashboard_title_dumb), new DumbFragment());
screens.put(getApplicationContext().getString(R.string.dashboard_title_messages), mMessagesFragment);
// instantiate view pager via adapter
mPager = (ViewPager) findViewById(R.id.viewpager_pager);
mPagerAdapter = new BasePagerAdapter(screens, getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
// set title indicator
TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.viewpager_titles);
indicator.setViewPager(mPager, 1);
}
/* set of fragments callback interface implementations */
@Override
public void onMessageInitialisation() {
Logger.d("Dash onMessageInitialisation");
if (mMessagesFragment != null)
mMessagesFragment.loadLastMessages();
}
@Override
public void onMessageSelected(Message selectedMessage) {
Intent intent = new Intent(this, StreamActivity.class);
intent.putExtra(Message.class.getName(), selectedMessage);
startActivity(intent);
}
BasePagerActivity Yardımcısı aka
public class BasePagerActivity extends FragmentActivity {
BasePagerAdapter mPagerAdapter;
ViewPager mPager;
}
Bağdaştırıcı
public class BasePagerAdapter extends FragmentPagerAdapter implements TitleProvider {
private Map<String, Fragment> mScreens;
public BasePagerAdapter(Map<String, Fragment> screenMap, FragmentManager fm) {
super(fm);
this.mScreens = screenMap;
}
@Override
public Fragment getItem(int position) {
return mScreens.values().toArray(new Fragment[mScreens.size()])[position];
}
@Override
public int getCount() {
return mScreens.size();
}
@Override
public String getTitle(int position) {
return mScreens.keySet().toArray(new String[mScreens.size()])[position];
}
// hack. we don't want to destroy our fragments and re-initiate them after
@Override
public void destroyItem(View container, int position, Object object) {
// TODO Auto-generated method stub
}
}
Parça
public class MessagesFragment extends ListFragment {
private boolean mIsLastMessages;
private List<Message> mMessagesList;
private MessageArrayAdapter mAdapter;
private LoadMessagesTask mLoadMessagesTask;
private OnMessageListActionListener mListener;
// define callback interface
public interface OnMessageListActionListener {
public void onMessageInitialisation();
public void onMessageSelected(Message selectedMessage);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// setting callback
mListener = (OnMessageListActionListener) activity;
mIsLastMessages = activity instanceof DashboardActivity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
inflater.inflate(R.layout.fragment_listview, container);
mProgressView = inflater.inflate(R.layout.listrow_progress, null);
mEmptyView = inflater.inflate(R.layout.fragment_nodata, null);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// instantiate loading task
mLoadMessagesTask = new LoadMessagesTask();
// instantiate list of messages
mMessagesList = new ArrayList<Message>();
mAdapter = new MessageArrayAdapter(getActivity(), mMessagesList);
setListAdapter(mAdapter);
}
@Override
public void onResume() {
mListener.onMessageInitialisation();
super.onResume();
}
public void onListItemClick(ListView l, View v, int position, long id) {
Message selectedMessage = (Message) getListAdapter().getItem(position);
mListener.onMessageSelected(selectedMessage);
super.onListItemClick(l, v, position, id);
}
/* public methods to load messages from host acitivity, etc... */
}
Çözüm
Aptal çözüm putFragment ile onSaveİnstanceState (ana Faaliyet) içindeki parçaları kaydetmek ve getFragment üzerinden onCreate içinde onları almak için. Ama yine de bazı şeyler... kod aşağıda: gibi değil garip bir his var
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager()
.putFragment(outState, MessagesFragment.class.getName(), mMessagesFragment);
}
protected void onCreate(Bundle savedInstanceState) {
Logger.d("Dash onCreate");
super.onCreate(savedInstanceState);
...
// create fragments to use
if (savedInstanceState != null) {
mMessagesFragment = (MessagesFragment) getSupportFragmentManager().getFragment(
savedInstanceState, MessagesFragment.class.getName());
StreamsFragment.class.getName());
}
if (mMessagesFragment == null)
mMessagesFragment = new MessagesFragment();
...
}
CEVAP
FragmentPagerAdapter
FragmentManager için bir parça ekler, parça yer alacak özel bir etiket belirli bir pozisyona bağlı olarak kullanır. FragmentPagerAdapter.getItem(int position)
bu pozisyon için bir parça yok sadece denir. Dönen sonra, Android zaten/kaydedilen bu özel konumu için bir parçasını oluşturan ve sadece onunla yeniden kurmaya çalışır yani FragmentManager.findFragmentByTag()
, yerine yeni bir tane oluşturmak ile göreceksiniz. Tüm bu FragmentPagerAdapter
kullanırken ücretsiz olarak geliyor ve her zamanki getItem(int)
yöntemin bölümü hazırlama kuralların varmış olmasıdır.
Eğer FragmentPagerAdapter
, Activity.onCreate(Bundle)
yeni bir parça her zaman oluşturmak için iyi bir fikir değildir bir kullanmıyor olsak bile. Fark ettiğiniz gibi, bir parça FragmentManager eklendiğinde, dönen sonra sizin için oluşturulur ve tekrar eklemeye gerek yok. Bunu yaparken olduğu parçaları ile çalışırken hatalara yol açabilir.
Parçaları ile çalışırken normal bir yaklaşımdır bu
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
CustomFragment fragment;
if (savedInstanceState != null) {
fragment = (CustomFragment) getSupportFragmentManager().findFragmentByTag("customtag");
} else {
fragment = new CustomFragment();
getSupportFragmentManager().beginTransaction().add(R.id.container, fragment, "customtag").commit();
}
...
}
Adaptör için ** 23, feragat parça yönetimi kullanırken, ve yukarıdaki adımları gerçekleştirmek gerekmez. Varsayılan olarak, yalnızca geçerli konum FragmentStatePagerAdapter
kullandığınız sürece, onları yok etmese de arkasında önünde ve bir Parça ön yük olacaktır. Bu ViewPager.setOffscreenPageLimit(int) tarafından kontrol edilir. Bu nedenle, doğrudan adaptör dışında parçaları yöntemleri çağırmak hayatta bile olmayabilir çünkü geçerli olması için garanti edilmez.
Kesmek uzun lafın kısası, çözüm için kullanın putFragment
edebilmek için bir başvuru daha sonra değil, o yüzden deli, ve bu yüzden aksine normal şekilde kullanın parçaları zaten (yukarıda). Parça adaptör ile, sizin kişisel eklenmez çünkü zor bir referans aksi takdirde elde etmek mümkündür. Ona güveniyor beri sadece offscreenPageLimit
Her zaman istediğiniz parçaları yüklemek için yeterince yüksek olduğundan emin olun, mevcut olmak. Bu ViewPager tembel yükleme yetenekleri atlar, ama uygulama için ne arzu gibi görünüyor.
Başka bir yaklaşım FragmentPageAdapter.instantiateItem(View, int)
geçersiz kılar ve parça iade etmeden önce süper çağrısından bir başvuru (zaten varsa bu parçayı bulmak için mantığı vardır) kurtarmaktır.
Daha dolgun bir görüntü için, FragmentPagerAdapter (kısa) ve ViewPager (uzun) kaynak bazılarına bir göz var.
Parçaları ilk veri vermek için doğru y...
Doğru kullanımı Android kullanıcısı Yö...
C için doğru sürüm numaraları ne#?...
Nasıl pi benim hesaplama doğru olup ol...
Hangi MySQL boolean değerleri saklamak...