fragmentpageradapter에서 조각 재사용
조각을 통해 페이지를 표시하는 뷰 페이저가 있습니다. 내 FragmentPagerAdapter
하위 클래스 getItem
는 낭비처럼 보이는 메서드 에서 새로운 조각을 만듭니다 . 거기 FragmentPagerAdapter
에 해당 convertView
에서 listAdapter
이미 생성 된 조각을 재사용하는 저를 가능하게 할 것이다 그? 내 코드는 다음과 같습니다.
public class ProfilePagerAdapter extends FragmentPagerAdapter {
ArrayList<Profile> mProfiles = new ArrayList<Profile>();
public ProfilePagerAdapter(FragmentManager fm) {
super(fm);
}
/**
* Adding a new profile object created a new page in the pager this adapter is set to.
* @param profile
*/
public void addProfile(Profile profile){
mProfiles.add(profile);
}
@Override
public int getCount() {
return mProfiles.size();
}
@Override
public Fragment getItem(int position) {
return new ProfileFragment(mProfiles.get(position));
}
}
는 FragmentPagerAdapter
이미 Fragments
당신을 위해 캐시합니다 . 각 조각은 태그를 할당하고는 FragmentPagerAdapter
전화를 시도합니다 findFragmentByTag
. 그것은 단지 호출 getItem
의 결과가있는 경우 findFragmentByTag
입니다 null
. 따라서 조각을 직접 캐시 할 필요가 없습니다.
Geoff의 게시물에 대한 부록 :
Fragment
를 FragmentPagerAdapter
사용하여 참조를 얻을 수 있습니다 findFragmentByTag()
. 태그 이름은 다음과 같이 생성됩니다.
private static String makeFragmentName(int viewId, int index)
{
return "android:switcher:" + viewId + ":" + index;
}
여기서 viewId는 ViewPager의 ID입니다.
이 질문을 보는 많은 사람들이 /에 Fragments
의해 만들어진 참조 방법을 찾고있는 것 같습니다 . 여기에있는 다른 답변이 사용 하는 내부적으로 생성 된 것에 의존하지 않고 이에 대한 솔루션을 제공하고 싶습니다 .FragmentPagerAdapter
FragmentStatePagerAdapter
tags
보너스로이 방법은 FragmentStatePagerAdapter
. 자세한 내용은 아래 참고를 참조하십시오.
현재 솔루션의 문제점 : 내부 코드에 의존
이 질문과 유사한 질문에 대해 내가 본 많은 솔루션 은 내부적으로 생성 된 태그를Fragment
호출 FragmentManager.findFragmentByTag()
하고 모방하여 기존 에 대한 참조를 얻는 데 의존합니다 .. 이것의 문제는 당신이 내부 소스 코드에 의존하고 있다는 것입니다. 우리 모두가 알고 있듯이 영원히 동일하게 유지된다는 보장은 없습니다. Google의 Android 엔지니어 는 기존 .NET에 대한 참조를 찾을 수 없도록 코드를 손상 시키는 구조를 쉽게 변경할 수 있습니다 ."android:switcher:" + viewId + ":" + id
tag
Fragments
내부에 의존하지 않는 대체 솔루션 tag
다음 은에 대한 내부 집합에 의존하지 않는 에서 Fragments
반환 된에 대한 참조를 가져 오는 방법에 대한 간단한 예입니다 . 핵심은 에서 대신 참조 를 재정의 하고 저장하는 것 입니다 .FragmentPagerAdapter
tags
Fragments
instantiateItem()
getItem()
public class SomeActivity extends Activity {
private FragmentA m1stFragment;
private FragmentB m2ndFragment;
// other code in your Activity...
private class CustomPagerAdapter extends FragmentPagerAdapter {
// other code in your custom FragmentPagerAdapter...
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// Do NOT try to save references to the Fragments in getItem(),
// because getItem() is not always called. If the Fragment
// was already created then it will be retrieved from the FragmentManger
// and not here (i.e. getItem() won't be called again).
switch (position) {
case 0:
return new FragmentA();
case 1:
return new FragmentB();
default:
// This should never happen. Always account for each position above
return null;
}
}
// Here we can finally safely save a reference to the created
// Fragment, no matter where it came from (either getItem() or
// FragmentManger). Simply save the returned Fragment from
// super.instantiateItem() into an appropriate reference depending
// on the ViewPager position.
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// save the appropriate reference depending on position
switch (position) {
case 0:
m1stFragment = (FragmentA) createdFragment;
break;
case 1:
m2ndFragment = (FragmentB) createdFragment;
break;
}
return createdFragment;
}
}
public void someMethod() {
// do work on the referenced Fragments, but first check if they
// even exist yet, otherwise you'll get an NPE.
if (m1stFragment != null) {
// m1stFragment.doWork();
}
if (m2ndFragment != null) {
// m2ndFragment.doSomeWorkToo();
}
}
}
또는에tags
대한 클래스 멤버 변수 / 참조 대신에 작업을 선호하는 경우 동일한 방식으로 집합을 Fragments
가져올 수도 있습니다 . 참고 : 를 만들 때 설정되지 않기 때문에 적용 되지 않습니다 .tags
FragmentPagerAdapter
FragmentStatePagerAdapter
tags
Fragments
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// get the tags set by FragmentPagerAdapter
switch (position) {
case 0:
String firstTag = createdFragment.getTag();
break;
case 1:
String secondTag = createdFragment.getTag();
break;
}
// ... save the tags somewhere so you can reference them later
return createdFragment;
}
Note that this method does NOT rely on mimicking the internal tag
set by FragmentPagerAdapter
and instead uses proper APIs for retrieving them. This way even if the tag
changes in future versions of the SupportLibrary
you'll still be safe.
Don't forget that depending on the design of your Activity
, the Fragments
you're trying to work on may or may not exist yet, so you have to account for that by doing null
checks before using your references.
Also, if instead you're working with FragmentStatePagerAdapter
, then you don't want to keep hard references to your Fragments
because you might have many of them and hard references would unnecessarily keep them in memory. Instead save the Fragment
references in WeakReference
variables instead of standard ones. Like this:
WeakReference<Fragment> m1stFragment = new WeakReference<Fragment>(createdFragment);
// ...and access them like so
Fragment firstFragment = m1stFragment.get();
if (firstFragment != null) {
// reference hasn't been cleared yet; do work...
}
If the fragment still in memory you can find it with this function.
public Fragment findFragmentByPosition(int position) {
FragmentPagerAdapter fragmentPagerAdapter = getFragmentPagerAdapter();
return getSupportFragmentManager().findFragmentByTag(
"android:switcher:" + getViewPager().getId() + ":"
+ fragmentPagerAdapter.getItemId(position));
}
Sample code for v4 support api.
I know this is (theoretically) not an answer to the question, but a different approach.
I had an issue where I needed to refresh the visible fragments. Whatever I tried, failed and failed miserably...
After trying so many different things, I have finally finish this using BroadCastReceiver
. Simply send a broadcast when you need to do something with the visible fragments and capture it in the fragment.
If you need some kind of a response as well, you can also send it via broadcast.
cheers
For future readers!
If you are thinking of reusing fragments with viewpager, best solution is to use ViewPager 2, since View Pager 2 make use of RecyclerView.
참고URL : https://stackoverflow.com/questions/6976027/reusing-fragments-in-a-fragmentpageradapter
'programing tip' 카테고리의 다른 글
Java에서 임의의 문자열을 생성하는 방법 (0) | 2020.10.31 |
---|---|
Android에서 ImageView의 최대 너비 및 높이 (0) | 2020.10.31 |
VM 및 PyCharm으로 사용자 지정 PYTHONPATH를 구성하는 방법은 무엇입니까? (0) | 2020.10.31 |
long int의 크기가 항상 4 바이트라고 가정 할 수 있습니까? (0) | 2020.10.31 |
ActiveRecord : 대량 할당 할 수있는 모델의 모든 속성을 얻는 방법은 무엇입니까? (0) | 2020.10.31 |