2013-06-25 3 views
1

ViewPager에 다른 조각을 보여주는 응용 프로그램을 만들고 있습니다. 나는이 같은 ViewPager 이러한 조각을 추가ViewPager에서 현재 보이는 조각의 인스턴스를 얻는 방법 :

public void intialiseViewPager() 
{ 
    List<Fragment> fragments = new Vector<Fragment>(); 
    numberOfTabs = application.currentReport.getODTabsList().size(); 
    for (int i = 0; i < numberOfTabs; i++)  
    { 
     ODTab tempTab = application.currentReport.getODTabsList().get(i); 
     if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT)) 
     { 
      GridFragment gridFragment = GridFragment.newInstance(tempTab.getTabId()); 
      fragments.add(gridFragment); 
     } 
     else if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT)) 
     { 
      NewChartFragment chartFragment = NewChartFragment.newInstance(tempTab.getTabId()); 
      fragments.add(chartFragment); 
     } 
    } 
    Log.d(TAG, "Current report fragments set to adapter: "+fragments.toString()); 
    mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragments); 
    mViewPager = (ViewPager)findViewById(R.id.pager); 
    mViewPager.setAdapter(mPagerAdapter); 
    mViewPager.setOffscreenPageLimit(0); 
    mViewPager.setOnPageChangeListener(this); 
} 

당신은 내가 조각에 문자열 (tempTab.getTabId())을 통과 볼 수 있듯이,이 라인 :

GridFragment gridFragment = GridFragment.newInstance(tempTab.getTabId()); 

조각에서 자신을 내가 이렇게

public static final GridFragment newInstance(String tabId) 
{ 
    GridFragment f = new GridFragment(); 
    Bundle bdl = new Bundle(2); 
    bdl.putString(TAB_ID, tabId); 
    f.setArguments(bdl); 
    return f; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    String tabId = getArguments().getString(TAB_ID); 
    if (application.currentReport != null) 
    { 
     this.odTab = application.currentReport.getODTabByTabId(tabId); 
    } 
    else 
    { 
     startActivity(new Intent(getActivity(), LoginScrActivity.class)); 
    } 
    super.onCreate(savedInstanceState); 
} 

이 모든 작업은 조각의 기본 빈 생성자를 재정의하지 않기 위해 수행됩니다. 권장하지 않는 것으로 알고 있습니다. . 이 작업을 수행 할 수있는 방법을

this.odTab = application.currentReport.getODTabByTabId(tabId); 

누군가가 나에게 설명해 주 시겠어요 :

지금 나는이 줄에 현재 보이는 조각에 넣어 odTab 개체의 인스턴스를 얻을 필요가? odTab 객체를 꺼낼 수 있도록 현재 보이는 프래그먼트 인스턴스를 얻으려면 어떻게해야합니까?

UPDATE :

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) 
{ 
    Log.d(TAG, "setUserVisibleHint invoked!"); 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser) 
    { 
     if (odTab != null && getActivity() != null) 
     { 
      Log.d(TAG, "Currently visable tab: "+odTab.getTabTitle()); 
      application.currentVisibleTab = odTab; 
     } 
    } 
} 

: 나는 내가이 같은 odTab의 인스턴스를 설정하고 있습니다 currentVisibleTab라고 응용 프로그램 클래스에 odTab 개체 인스턴스를 추가 한 여기받은 제안 UPDATE2 : 이것은 내 ViewPagerAdapter입니다 :

public class ViewPagerAdapter extends FragmentPagerAdapter 
{ 
private List<Fragment> fragments; 

/** 
* @param fm 
* @param fragments 
*/ 
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) { 
    super(fm); 
    this.fragments = fragments; 
} 

/* (non-Javadoc) 
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int) 
*/ 

@Override 
public Fragment getItem(int position) { 
    return this.fragments.get(position); 
} 

/* (non-Javadoc) 
* @see android.support.v4.view.PagerAdapter#getCount() 
*/ 

@Override 
public int getCount() { 
    return this.fragments.size(); 
} 

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

public void removeAllFragments() 
{ 
    this.fragments.clear(); 
} 

public void addFragmentsListToAdapter(List<Fragment> fragments) 
{ 
    this.fragments.addAll(fragments); 
} 

public List<Fragment> getFragments() 
{ 
    return fragments; 
} 
} 

List의 조각이 ViewPager으로 표시됩니다. 이 목록은 다음과 같이 초기화 :

List<Fragment> fragments = new Vector<Fragment>(); 

은 내가 이해할 수없는 것은 내가이 목록에서 인터페이스 메서드를 트리거 현재의 단편에 대한 참조를 가져 방법이다. 그리고 이것은 관련 질문이 아니지만 어쩌면 그 대답을 알고있을 것입니다 : ListVector의 차이점은 무엇입니까?

이 옵션을 계속 선택합니다.

+0

http://stackoverflow.com/questions/10024739/how-to-determine-when-fragment-becomes-visible-in-viewpager. 이것을 확인하십시오 – Raghunandan

+0

안녕하세요 @Raghunandan, 나는 "setUserVisibleHint"옵션을 시도했지만 어떤 이유로 그것을 올바르게 처리하지 못했습니다. 그래서 나는 이것이 방법이 아니라는 것을 알아 냈습니다. 다시 한번 살펴 보겠습니다. –

+0

은'setUserVisibleHint'를 무시하고'setUserVisibleHint' 안에서'GridFragment.newInstance (tabId)'를 사용합니다. 인스턴스를 기록하고 확인하십시오. 테스트되지 않은 제안. – Raghunandan

답변

6

현재 보이는 조각은 setUserVisibleHint이고 인터페이스는 ViewPager입니다. 이 메서드는 fragment 클래스에 있습니다. 이를 무시하고 인터페이스를 사용하여 ViewPager으로 다시 전화하십시오. 프래그먼트가 표시되면 (즉, true를 반환하는 경우) 프래그먼트 자체에서 필요한 것을 얻기 위해 프래그먼트 (어댑터를 지원하는 목록 또는 인스턴스 변수로 저장 한 목록 중 하나)에 대한 참조 만 사용하십시오. 아래 코드를 추가했습니다.

원하는 작업과 관련된 인터페이스를 선언하십시오. 제 경우에는 이것을 사용하여 Google지도 인스턴스가 표시되었을 때기본 x 방향 수신기를 사용 중지하여지도를 스크롤하면 조각 변경이 트리거되지 않았습니다.조각에서

public interface OnMapFragmentVisibleListener{ 
    public void mapVisible(boolean visible); 
} 

:

@Override 
public void onAttach(Activity activity){ 
    super.onAttach(activity); 
    try{ 
     mapFragmentVisibilityListener = (OnMapFragmentVisibleListener) activity; 
     isAttached = true; //flag for whether this fragment is attached to pager 
    } catch (ClassCastException e){ 
     throw new ClassCastException(activity.toString() + " must implement interface onAttach"); 
    } 


@Override 
public void setUserVisibleHint(boolean isVisibleToUser){ 
    if(isVisibleToUser && isAttached){ //if listener is called before fragment is attached will throw NPE 
     mapFragmentVisibilityListener.mapVisible(true); 
    } 
} 

한 가지 나는이 밖으로 시도 할 때까지 분명 아니었다 isAttached 변수를 추가했다. 또한 onAttach 메서드를 파기 한 다음이 메서드를 호출하면 true로 설정합니다. 그렇지 않으면 사용자의 조각이 사용자에게 표시되고 인터페이스가 초기화되기 전에 ViewPager에 대한 인터페이스 호출을 시도합니다. 내 ViewPager에서

은 그냥 OnMapFragmentVisibleListener를 구현하고 나는 그것이 ViewPager 슬쩍 기능을 해제하는 데 사용 후, 내 경우에는 필요한 방법을

@Override 
public void mapVisible(boolean visible) { 
    if(visible) 
    viewPager.allowSwipe(false); //turn off viewPager intercept touch if map visible 
} 

를 추가합니다. 그러나 쉽게 mapFragment에서 공용 메서드를 다시 호출 할 수있었습니다. 나는 내 참조를 유지하는 내 ViewPager에 3 조각을 가지고 일이.

업데이트

현재, 당신이 먼저 표시되고있는 단편 알아 내야 표시되는 조각을 찾을 수 있습니다. 이것을 여러 가지 방법으로 할 수 있습니다. 가장 쉬운 방법은 전에 작성한 인터페이스를 사용하여 일부 설명자를 ViewPager/FragmentActivity으로 다시 전달하는 것입니다.

public interface OnFragmentVisibleListener{ 
    public void fragmentVisible(boolean true, String tag); 
} 

셋업의 문제는 당신이 정말로 당신의 조각 참조를 저장하는 동기 ListVector를 사용하고 있다는 점이다. 따라서 나중에 조각을 찾을 수있는 핵심 가치가 없습니다. 조각은 조각 활동 중에 추가 된 조각 트랜잭션 동안 만들어진 태그로 식별 할 수 있습니다. 그러나 ViewPager 설치에서는 조각을 개별적으로 추가하지 않으므로 트랜잭션 중에 태그를 추가 할 수 없습니다.

해결 방법 내 BasePagerAdapterHashMap으로 백업하고 고유 키로 식별 된 각 조각을 저장했습니다.

LinkedHashMap<String, Fragment> tabs = new LinkedHashMap<String, Fragment>(); 
tabs.put("Frag1", fragment1); 
tabs.put("Frag2", fragment2); 
tabs.put("Frag3", fragment3); 

그럼 난 어댑터에서 이것을 사용

private class BasePagerAdapter extends FragmentPagerAdapter{ 

    private LinkedHashMap<String, Fragment> tabs; 

    public BasePagerAdapter(LinkedHashMap<String, Fragment> tabMap, FragmentManager fm) 
    { 
     super(fm); 
     this.tabs = tabMap; 
    } 

    // other basic methods 

당신의 참조를 키 값으로 저장되기 때문에, 그것은 당신이 방금에서 키를 검색 할 수 있기 때문에 찾고있는 조각을 쉽게 찾을 수 HashMap 및 반환.

Vector에서 벗어나기 위해 설정을 변경할 수없는 경우 (1) 조각을 추가하거나 제거하지 않으면 어떤 순서로 추가 할지를 추적해야합니다. 색인 또는 (2) 각 조각에 대한 별도의 참조를 유지하십시오.

private Fragment x; 

//in onCreate 
x = new Fragment(); 

//in interface 
if(tag.equals("x"){ 
    x.doSomething(); 
} 

이렇게 쉽게 만드는 또 다른 사항은 내 조각이 모두 하위 분류 된 것입니다. 예 : 다른 기능을 수행하는 각 조각에는 자체 클래스가 있습니다. 각 클래스에는 단 하나의 인스턴스 만 있으므로 중복이 없으므로 쉽게 찾을 수 있습니다. Fragment 클래스의 모든 일반 멤버를 사용하는 경우 위의 방법 중 하나를 가능하게하는 태그 지정 시스템을 구현하기 만하면됩니다.

+0

조각 측 및 viewPager 측 클래스에서 어떻게 수행했는지에 대한 코드 스 니펫 중 일부를 제공해 주실 수 있습니까? –

+0

방금 ​​추가되었습니다. 미안 해요. 대답하기 전에 책상에 앉기 전에 게시하지 않았습니다. – Rarw

+0

고마워요. 훌륭한 답변입니다. 내 문제를 해결할 수 있다면 답을 수락하고, 한편으로는 노력에 +1하십시오. –

3

다음과 같은 방법으로 viewpager.getCurrentItem() 메소드를 사용하여 현재 눈에 보이는 조각을 얻을 수 있습니다 :

조각 FR =에서 getSupportFragmentManager() findFragmentByTag (. "안드로이드 : 스위처 :"+ R.id.pager + " : "+ mViewPager.getCurrentItem());

덕분에,

Sulabh

관련 문제