View Pager에서 조각 검색
사용 중입니다.ViewPager
과 FragmentStatePagerAdapter
fragment를 : 개의 다합호스다니트세을각조른.
- [분절1]
- [분절2]
- [분절3]
내가 얻고 싶을 때Fragment1
ViewPager
에 시대에FragmentActivity
.
무엇이 문제이며 어떻게 해결해야 합니까?
기본 응답은 프레임워크에서 생성되는 이름에 의존합니다.만약 그것이 바뀌면, 그것은 더 이상 작동하지 않을 것입니다.
이 해결책은 어때요, 오버라이드instantiateItem()
그리고.destroyItem()
의 신의의Fragment(State)PagerAdapter
:
public class MyPagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return ...;
}
@Override
public Fragment getItem(int position) {
return MyFragment.newInstance(...);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
이것은 사용 가능한 Fragment를 처리할 때 저에게 효과가 있는 것 같습니다.는 직는아을은호출시다니환반합않인을 합니다.getRegisteredFragment
하지만 난 이걸 주로 전류를 얻기 위해 사용해왔어요Fragment
에서 .ViewPager
:adapater.getRegisteredFragment(viewPager.getCurrentItem())
그리고 이것은 돌아오지 않을 것입니다.null
.
저는 이 솔루션의 다른 단점을 알지 못합니다.있다면 알고 싶습니다.
ViewPager에서 단편을 수집하는 방법은 여기 및 기타 관련 SO 스레드/블로그에 많은 답변이 있습니다.제가 본 사람들은 모두 고장이 났고, 일반적으로 아래 두 가지 유형 중 하나에 해당하는 것 같습니다.이 스레드의 다른 답변과 같이 현재 조각만 가져오려는 경우 다른 유효한 해결책이 있습니다.
사용하는 경우 아래를 참조하십시오.이것을 볼 가치가 있다면요.FragmentStateAdapter에서 현재 인덱스가 아닌 인덱스를 가져오는 것은 그 특성상 완전히 해체되는 것만큼 유용하지 않습니다. 이러한 인덱스는 보기에서 사라지거나 화면 밖으로 사라집니다.
불행한 길들
Wrong: 내부 조각 목록을 관리하고 다음에 추가합니다.FragmentPagerAdapter.getItem()
를 라고 합니다.
- 일반적으로 a를 사용합니다.
SparseArray
또는Map
- 라이프사이클 이벤트를 설명하는 많은 예 중 하나가 아니기 때문에 이 솔루션은 취약합니다.
getItem
페이지를 처음으로 스크롤할 때만 호출됩니다.ViewPager.setOffscreenPageLimit(x)
> 0)ViewPager
가 주최가라면.Activity
/Fragment
작동이 중지되거나 다시 시작되면 내부가SpaseArray
FragmentPager 때되지만, 되고 "FragmentPager Activity", "ViewPager" 및 "Fragment"가 재생성됩니다.getItem
인덱스에 대해 호출되지 않으므로 인덱스에서 조각을 가져오는 기능이 영구히 손실됩니다.다음을 통해 이러한 조각 참조를 저장하고 복원하여 이 문제를 해결할 수 있습니다.FragmentManager.getFragment()
그리고.putFragment
IMHO가 엉망이 되기 시작합니다.
Wrong: 의 후드 아래에 사용되는 태그 ID와 일치하도록 자체 태그 ID를 구성하고 이 ID를 사용하여 페이지 Fragments를 검색합니다.FragmentManager
- 이것은 첫 번째 내부 어레이 솔루션에서 손실-분절-참조 문제를 처리하는 것과 같은 경우에 더 낫지만, 위와 인터넷의 다른 곳에서 올바르게 지적된 바와 같이, 내부의 개인적인 방법만큼이나 진부하게 느껴집니다.
ViewPager
언제든지 또는 OS 버전에 따라 변경될 수 있습니다.
이 솔루션에 대해 다시 생성된 방법은 다음과 같습니다.
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
한 경로: 행한길복:ViewPager.instantiateItem()
위와 유사한 접근 방식이지만 라이프사이클 파괴가 아닌 접근 방식은 다음과 같습니다.instantiateItem()
에 getItem()
인덱스가 생성/액세스될 때마다 전자가 호출되기 때문입니다.이 답변 보기
PATH: 만의 길을 .FragmentViewPager
만의 접직을 합니다.FragmentViewPager
최신 지원 lib 소스에서 클래스를 생성하고 fragment 태그를 생성하는 데 내부적으로 사용되는 메서드를 변경합니다.아래와 같이 대체할 수 있습니다.이는 태그 생성이 변경되지 않고 항상 위험한 개인 api/method에 의존하지 않는다는 것을 가지고 있습니다.
/**
* @param containerViewId the ViewPager this adapter is being supplied to
* @param id pass in getItemId(position) as this is whats used internally in this class
* @return the tag used for this pages fragment
*/
public static String makeFragmentName(int containerViewId, long id) {
return "android:switcher:" + containerViewId + ":" + id;
}
처럼 인덱스에 싶을 때 에 넣을 수)을 불러주세요.FragmentPagerAdapter
getItem이 해당 페이지에 대해 아직 호출되지 않은 경우(즉, 아직 생성되지 않은 경우) 결과가 null일 수 있습니다.
/**
* @return may return null if the fragment has not been instantiated yet for that position - this depends on if the fragment has been viewed
* yet OR is a sibling covered by {@link android.support.v4.view.ViewPager#setOffscreenPageLimit(int)}. Can use this to call methods on
* the current positions fragment.
*/
public @Nullable Fragment getFragmentForPosition(int position)
{
String tag = makeFragmentName(mViewPager.getId(), getItemId(position));
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
return fragment;
}
이것은 간단한 솔루션이며 웹의 모든 곳에서 발견되는 다른 두 솔루션의 문제를 해결합니다.
FragmentPager 어댑터에 다음 메서드를 추가합니다.
public Fragment getActiveFragment(ViewPager container, int position) {
String name = makeFragmentName(container.getId(), position);
return mFragmentManager.findFragmentByTag(name);
}
private static String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
getActiveFragment(0)가 작동해야 합니다.
다음은 ViewPager https://gist.github.com/jacek-marchwicki/d6320ba9a910c514424d 에 구현된 솔루션입니다.무언가 실패하면 양호한 충돌 로그가 표시됩니다.
또 다른 간단한 솔루션:
public class MyPagerAdapter extends FragmentPagerAdapter {
private Fragment mCurrentFragment;
public Fragment getCurrentFragment() {
return mCurrentFragment;
}
//...
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (getCurrentFragment() != object) {
mCurrentFragment = ((Fragment) object);
}
super.setPrimaryItem(container, position, object);
}
}
이것이 몇 가지 답을 가지고 있다는 것을 알지만, 아마도 이것은 누군가에게 도움이 될 것입니다.비교적 간단한 솔루션을 사용했습니다.Fragment
의 게서에서.ViewPager
의 신의에서.Activity
또는Fragment
를 ViewPager
이 코드를 사용하여 다음과 같이 순환할 수 있습니다.Fragment
그것은 유지됩니다.
FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
Fragment viewPagerFragment = fragmentPagerAdapter.getItem(i);
if(viewPagerFragment != null) {
// Do something with your Fragment
// Check viewPagerFragment.isResumed() if you intend on interacting with any views.
}
}
이 당신의 ,
Fragment
에 시대에ViewPager
그냥 전화하시면 됩니다.getItem(knownPosition)
.이 당신의 .
Fragment
에 시대에ViewPager
당신은 당신의 아이들을 가질 수 있습니다.Fragments
할 때는 " 과같방법인로구터현다니합를스이페다으음은▁like▁an▁with▁interface"와 같은 방법을 합니다.getUniqueId()
그리고 그것을 사용하여 그들을 차별화합니다.또는 모두 순환할 수 있습니다.Fragments
유형을 합니다. 를 들어, 클래스 유형을 확인합니다.if(viewPagerFragment instanceof FragmentClassYouWant)
편집!!!
는 그것을 했습니다.getItem
에 의해서만 호출됩니다.FragmentPagerAdapter
각각의 경우에Fragment
처음 생성되어야 하고, 그 후에, 그것은 나타납니다.Fragments
▁the를 사용하여 됩니다.FragmentManager
식으로, 이한방식로, 구이현많의 많은 이 있습니다.FragmentPagerAdapter
새로 만들기 Fragment
죄를 짓는getItem
위의 방법을 사용하면, 이것은 우리가 새로운 것을 만들 것이라는 것을 의미합니다.Fragment
번매getItem
우리가 모든 항목을 검토할 때 호출됩니다.FragmentPagerAdapter
이로 인해, 저는 더 나은 접근법을 찾았습니다.FragmentManager
각각을 얻기 위해Fragment
대신(승인된 답변 사용).이것은 더 완벽한 해결책이며, 저에게 잘 작동하고 있습니다.
FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
String name = makeFragmentName(mViewPager.getId(), i);
Fragment viewPagerFragment = getChildFragmentManager().findFragmentByTag(name);
// OR Fragment viewPagerFragment = getFragmentManager().findFragmentByTag(name);
if(viewPagerFragment != null) {
// Do something with your Fragment
if (viewPagerFragment.isResumed()) {
// Interact with any views/data that must be alive
}
else {
// Flag something for update later, when this viewPagerFragment
// returns to onResume
}
}
}
그리고 당신은 이 방법이 필요할 것입니다.
private static String makeFragmentName(int viewId, int position) {
return "android:switcher:" + viewId + ":" + position;
}
저의 경우, 위의 해결책 중 하나도 효과가 없었습니다.
그러나 fragment에서 하위 fragment Manager를 사용하고 있기 때문에 다음이 사용되었습니다.
Fragment f = getChildFragmentManager().getFragments().get(viewPager.getCurrentItem());
이것은 관리자의 조각이 보기 페이지 항목과 일치하는 경우에만 작동합니다.
ViewPager에서 현재 Visible fragment를 가져오려면 다음과 같이 하십시오.저는 이 간단한 문구를 사용하고 있으며 잘 작동하고 있습니다.
public Fragment getFragmentFromViewpager()
{
return ((Fragment) (mAdapter.instantiateItem(mViewPager, mViewPager.getCurrentItem())));
}
했습니다. (우 모 조 처 습 했 니 리 다 로 것 으 는 선 하 든List<Fragment> fragments;
)을 조각을 쉽게 할 수 을 사용하여 호출기에 추가함으로써 현재 표시된 단편을 쉽게 처리할 수 있습니다.
그래서:
@Override
onCreate(){
//initialise the list of fragments
fragments = new Vector<Fragment>();
//fill up the list with out fragments
fragments.add(Fragment.instantiate(this, MainFragment.class.getName()));
fragments.add(Fragment.instantiate(this, MenuFragment.class.getName()));
fragments.add(Fragment.instantiate(this, StoresFragment.class.getName()));
fragments.add(Fragment.instantiate(this, AboutFragment.class.getName()));
fragments.add(Fragment.instantiate(this, ContactFragment.class.getName()));
//Set up the pager
pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager(), fragments));
pager.setOffscreenPageLimit(4);
}
그래서 이것은 다음과 같이 불릴 수 있습니다.
public Fragment getFragment(ViewPager pager){
Fragment theFragment = fragments.get(pager.getCurrentItem());
return theFragment;
}
그래서 나는 그것이 올바른 조각에 있을 때만 실행되는 if 문에 그것을 버릴 수 있었습니다.
Fragment tempFragment = getFragment();
if(tempFragment == MyFragmentNo2.class){
MyFragmentNo2 theFrag = (MyFragmentNo2) tempFragment;
//then you can do whatever with the fragment
theFrag.costomFunction();
}
하지만 그것은 단지 나의 해킹과 슬래시 접근법일 뿐이지만, 그것은 나에게 효과가 있었고, 나는 뒤로 버튼을 눌렀을 때 현재 표시된 내 조각에 관련된 변경을 하는 것을 사용합니다.
이것은 위의 스티븐의 답변에 근거한 것입니다.이렇게 하면 부모 활동에 이미 연결된 조각의 실제 인스턴스가 반환됩니다.
FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
Fragment viewPagerFragment = (Fragment) mViewPager.getAdapter().instantiateItem(mViewPager, i);
if(viewPagerFragment != null && viewPagerFragment.isAdded()) {
if (viewPagerFragment instanceof FragmentOne){
FragmentOne oneFragment = (FragmentOne) viewPagerFragment;
if (oneFragment != null){
oneFragment.update(); // your custom method
}
} else if (viewPagerFragment instanceof FragmentTwo){
FragmentTwo twoFragment = (FragmentTwo) viewPagerFragment;
if (twoFragment != null){
twoFragment.update(); // your custom method
}
}
}
}
저는 이것을 하는 간단하고 깨끗한 방법을 찾을 수 없었습니다.그러나 ViewPager 위젯은 조각을 호스트하는 또 다른 ViewGroup일 뿐입니다.ViewPager에는 이러한 조각이 즉시 하위 항목으로 포함되어 있습니다.따라서 .getChildCount() 및 .getChildAt()를 사용하여 이를 반복하고, 찾고 있는 조각 인스턴스가 현재 ViewPager에 로드되어 있는지 확인하고 참조할 수 있습니다. 예를 들어 정적 고유 ID 필드를 사용하여 조각을 구분할 수 있습니다.
ViewPager는 ListView와 같은 가상화 컨테이너이므로 원하는 조각을 로드하지 않았을 수 있습니다.
FragmentPagerAdapter는 fragment의 팩토리입니다.메모리에 남아 있는 경우 위치를 기준으로 fragment를 찾으려면 다음을 사용합니다.
public Fragment findFragmentByPosition(int position) {
FragmentPagerAdapter fragmentPagerAdapter = getFragmentPagerAdapter();
return getSupportFragmentManager().findFragmentByTag(
"android:switcher:" + getViewPager().getId() + ":"
+ fragmentPagerAdapter.getItemId(position));
}
v4 지원 API의 샘플 코드입니다.
전화할 필요가 없습니다.getItem()
또는 나중 단계에서 어떤 다른 방법을 사용하여 a의 참조를 얻습니다.Fragment
안에주는하에서 ViewPager
내부의 일부 데이터를 .Fragment
그런 다음 ViewPager를 동적으로 업데이트하시겠습니까?
핵심은 내부에 새 데이터를 설정하는 것입니다.Adaper
와를 요.notifyDataSetChanged()
차례로 전화를 걸 것입니다.getItemPosition()
당신에게 당신의 추천서를 전달합니다.Fragment
업데이트할 수 있는 기회를 제공합니다.다른 모든 방법으로 자신이나 다른 해킹에 대한 참조를 요구하지만 이는 좋은 해결책이 아닙니다.
@Override
public int getItemPosition(Object object) {
if (object instanceof UpdateableFragment) {
((UpdateableFragment) object).update(xyzData);
}
//don't return POSITION_NONE, avoid fragment recreation.
return super.getItemPosition(object);
}
을 확장해야 .FragmentPagerAdapter
ViewPager 어댑터 클래스로 이동합니다.
사용하는 경우FragmentStatePagerAdapter
그러면 당신은 당신의 것을 찾을 수 없을 것입니다.Fragment
그 자체로ID
public static String makeFragmentName(int viewPagerId, int index) {
return "android:switcher:" + viewPagerId + ":" + index;
}
이 방법의 사용 방법:-
Fragment mFragment = ((FragmentActivity) getContext()).getSupportFragmentManager().findFragmentByTag(
AppMethodUtils.makeFragmentName(mViewPager.getId(), i)
);
InterestViewFragment newFragment = (InterestViewFragment) mFragment;
안녕하세요, 저는 여기서 이 질문에 답했습니다.기본적으로, 당신은 당신을 무시할 필요가 있습니다.
공용 개체 인스턴스화 항목(ViewGroup 컨테이너, 위치)
FragmentStatePagerAdapter 메서드입니다.
최상의 솔루션은 SmartFragmentStatePagerAdapter라는 CodePath에서 만든 확장을 사용하는 것입니다.이 안내서를 사용하면 ViewPager에서 조각 및 현재 선택한 조각을 훨씬 쉽게 검색할 수 있습니다.또한 어댑터에 내장된 단편의 메모리를 더 잘 관리할 수 있습니다.
가장 쉽고 간결한 방법. 조이들각든에 있는 ViewPager
검색하여 다음과 같이 구분할 수 있는 클래스가 서로 다릅니다.
public class MyActivity extends Activity
{
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment.getClass() == MyFragment.class) {
mMyFragment = (MyFragment) fragment;
}
}
}
저는 이것을 조금 다른 접근 방식으로 쉽게 구현했습니다.
내 사용자 지정 FragmentAdapter.getItem 메서드가 새 MyFragment()가 아니라 FragmentAdapter 생성자에 생성된 MyFragment의 인스턴스를 반환했습니다.
활동 중에 어댑터에서 fragment를 가져와 instanceOf required fragment인지 확인한 다음 필요한 메소드를 캐스트하여 사용합니다.
/values/integers.xml에 정수 리소스 ID 생성
<integer name="page1">1</integer>
<integer name="page2">2</integer>
<integer name="page3">3</integer>
그런 다음 PagerAdapter getItem 함수에서 다음을 수행합니다.
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = FragmentOne.newInstance();
mViewPager.setTag(R.integer.page1,fragment);
}
else if (position == 1) {
fragment = FragmentTwo.newInstance();
mViewPager.setTag(R.integer.page2,fragment);
} else if (position == 2) {
fragment = FragmentThree.newInstance();
mViewPager.setTag(R.integer.page3,fragment);
}
return fragment;
}
그런 다음 활동 중에 이 함수를 작성하여 fragment 참조를 가져옵니다.
private Fragment getFragmentByPosition(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = (Fragment) mViewPager.getTag(R.integer.page1);
break;
case 1:
fragment = (Fragment) mViewPager.getTag(R.integer.page2);
break;
case 2:
fragment = (Fragment) mViewPager.getTag(R.integer.page3);
break;
}
return fragment;
}
위 함수를 호출하여 fragment 참조를 얻은 다음 사용자 정의 fragment에 캐스트합니다.
Fragment fragment = getFragmentByPosition(position);
if (fragment != null) {
FragmentOne fragmentOne = (FragmentOne) fragment;
}
fragment 관리자에서 fragment를 쉽게 반복할 수 있습니다.공개 정적 플레이스홀더 조각 newInstance(int sectionNumber)에 배치된 횡단 위치 인수가 있는 뷰페이지를 찾습니다.
public PlaceholderFragment getFragmentByPosition(Integer pos){
for(Fragment f:getChildFragmentManager().getFragments()){
if(f.getId()==R.id.viewpager && f.getArguments().getInt("SECTNUM") - 1 == pos) {
return (PlaceholderFragment) f;
}
}
return null;
}
조각 속에
public int getArgument(){
return mPage;
{
public void update(){
}
조각 작업 중
List<Fragment> fragments = getSupportFragmentManager().getFragments();
for(Fragment f:fragments){
if((f instanceof PageFragment)&&(!f.isDetached())){
PageFragment pf = (PageFragment)f;
if(pf.getArgument()==pager.getCurrentItem())pf.update();
}
}
TabLayout에는 Fragment에 대한 여러 탭이 있습니다.조각의 인덱스를 사용하여 태그별로 조각을 찾을 수 있습니다.
를 들어,이므로, fragment1은 0입니다.findFragmentByTag()
메서드는 Viewpager에 대한 태그를 전달합니다.fragmentTransaction을 사용한 후 추가할 수 있는 fragment를 바꿉니다.
String tag = "android:switcher:" + R.id.viewPager + ":" + 0; Fragment1 f = (Fragment1) getSupportFragmentManager().findFragmentByTag(tag);
입니다.FragmentStatePagerAdapter
해결책에 자금을 지원합니다.
조각 작업:
ActionBar mActionBar = getSupportActionBar();
mActionBar.addTab(mActionBar.newTab().setText("TAB1").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment1.class.getName())));
mActionBar.addTab(mActionBar.newTab().setText("TAB2").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment2.class.getName())));
mActionBar.addTab(mActionBar.newTab().setText("TAB3").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment3.class.getName())));
viewPager = (STViewPager) super.findViewById(R.id.viewpager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), mActionBar);
viewPager.setAdapter(this.mPagerAdapter);
클래스에 메서드를 만듭니다. Fragment Activity - 이 메서드를 사용하면 Fragment에 액세스할 수 있습니다. 원하는 Fragment의 위치만 지정하면 됩니다.
public Fragment getActiveFragment(int position) {
String name = MyPagerAdapter.makeFragmentName(position);
return getSupportFragmentManager().findFragmentByTag(name);
}
어댑터:
public class MyPagerAdapter extends FragmentStatePagerAdapter {
private final ActionBar actionBar;
private final FragmentManager fragmentManager;
public MyPagerAdapter(FragmentManager fragmentManager, com.actionbarsherlock.app.ActionBarActionBar mActionBar) {super(fragmentManager);
this.actionBar = mActionBar;
this.fragmentManager = fragmentManager;
}
@Override
public Fragment getItem(int position) {
getSupportFragmentManager().beginTransaction().add(mTchatDetailsFragment, makeFragmentName(position)).commit();
return (Fragment)this.actionBar.getTabAt(position);
}
@Override
public int getCount() {
return this.actionBar.getTabCount();
}
@Override
public CharSequence getPageTitle(int position) {
return this.actionBar.getTabAt(position).getText();
}
private static String makeFragmentName(int viewId, int index) {
return "android:fragment:" + index;
}
}
Fragment yourFragment = yourviewpageradapter.getItem(int index);
index
당신이 추가한 것처럼 어댑터의 조각 위치입니다.fragment1
최초의 소굴의fragment1
통과하다index
휴식을 위해 0 등으로
언급URL : https://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager
'programing' 카테고리의 다른 글
데이터 테이블 에이잭스 예외 후 사용자 지정 오류 메시지 (0) | 2023.09.05 |
---|---|
JSF를 Spring MVC의 뷰 기술로 활용 (0) | 2023.09.05 |
Windows 서버에서 MySQL 데이터베이스 자동 백업 (0) | 2023.09.05 |
파이썬 팬더와 퍼지 매치 병합을 할 수 있습니까? (0) | 2023.09.05 |
CSS3 선택기: 클래스 이름을 가진 첫 번째 유형? (0) | 2023.09.05 |