development

현재 표시된 조각을 어떻게 얻습니까?

big-blog 2020. 2. 21. 22:26
반응형

현재 표시된 조각을 어떻게 얻습니까?


Android에서 조각으로 놀고 있습니다.

다음 코드를 사용하여 조각을 변경할 수 있다는 것을 알고 있습니다.

FragmentManager fragMgr = getSupportFragmentManager();
FragmentTransaction fragTrans = fragMgr.beginTransaction();

MyFragment myFragment = new MyFragment(); //my custom fragment

fragTrans.replace(android.R.id.content, myFragment);
fragTrans.addToBackStack(null);
fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragTrans.commit();

내 질문은 Java 파일에서 현재 표시된 Fragment 인스턴스를 어떻게 얻을 수 있습니까?


트랜잭션에 프래그먼트를 추가 할 때 태그를 사용해야합니다.

fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT");

... 그리고 나중에 조각이 보이는지 확인하려면 다음을 수행하십시오.

MyFragment myFragment = (MyFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment != null && myFragment.isVisible()) {
   // add your code here
}

참조 http://developer.android.com/reference/android/app/Fragment.html


나는 그것이 오래된 게시물이라는 것을 알고 있지만 이전에도 문제가있었습니다. onBackStackChanged()청취 기능 에서이 작업을 수행하는 솔루션을 찾았습니다.

  @Override
    public void onBackPressed() {
        super.onBackPressed();

         Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
      if(f instanceof CustomFragmentClass) 
        // do something with f
        ((CustomFragmentClass) f).doSomething();

    }

보이는 조각을 찾아야하는 모든 조각을 반복하고 싶지 않기 때문에 이것은 나를 위해 일했습니다. 그것이 다른 누군가에게도 도움이되기를 바랍니다.


낮은 조각 시나리오에 유용한 솔루션은 다음과 같습니다.

public Fragment getVisibleFragment(){
    FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    if(fragments != null){
        for(Fragment fragment : fragments){
            if(fragment != null && fragment.isVisible())
                return fragment;
        }
    }
    return null;
}

프래그먼트를 표시 할 때마다 태그를 백 스택에 넣어야합니다.

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);       
ft.add(R.id.primaryLayout, fragment, tag);
ft.addToBackStack(tag);
ft.commit();        

그런 다음 현재 조각을 가져와야 할 때이 방법을 사용할 수 있습니다.

public BaseFragment getActiveFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag);
}

현재 표시 조각을 찾는 데 사용하는 것은 아래 코드에 있습니다. 그것은 간단하고 지금까지 나를 위해 작동합니다. 조각을 보유하는 활동에서 실행됩니다.

    FragmentManager fragManager = this.getSupportFragmentManager();
    int count = this.getSupportFragmentManager().getBackStackEntryCount();
    Fragment frag = fragManager.getFragments().get(count>0?count-1:count);

반응 방법 :

Observable.from(getSupportFragmentManager().getFragments())
    .filter(fragment -> fragment.isVisible())
    .subscribe(fragment1 -> {
        // Do something with it
    }, throwable1 -> {
        // 
    });

내 방법은 다음과 같이 try / catch를 기반으로합니다.

MyFragment viewer = null;
    if(getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT) instanceOf MyFragment){
    viewer = (MyFragment) getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT);
}

그러나 더 좋은 방법이있을 수 있습니다 ...


글쎄,이 질문은 많은 견해와 관심을 얻었지만 getFragments ()를 사용하는 가장 쉬운 해결책은 포함하지 않았습니다.

            List fragments = getSupportFragmentManager().getFragments();
            mCurrentFragment = fragments.get(fragments.size() - 1);

조금 늦었지만 관심있는 사람이라면 FragmentManager에서 원하는 조각의 색인을 알고 있다면 그것에 대한 참조를 얻고 isMenuVisible () 함수를 확인하십시오! 여기 :

getSupportFragmentManager().getFragments().get(0).isMenuVisible()

true사용자 등에 게 보이는 경우 !


1)

ft.replace(R.id.content_frame, fragment, **tag**).commit();

2)

FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentById(R.id.content_frame);

삼)

if (currentFragment.getTag().equals(**"Fragment_Main"**))
{
 //Do something
}
else
if (currentFragment.getTag().equals(**"Fragment_DM"**))
{
//Do something
}

활동 컨텐츠 프레임에로드 된 프래그먼트를 조회하고 프래그먼트 클래스 또는 프래그먼트 '단순 이름'(문자열)을 검색 할 수 있습니다.

public String getCurrentFragment(){
     return activity.getSupportFragmentManager().findFragmentById(R.id.content_frame).getClass().getSimpleName();
}

용법:

Log.d(TAG, getCurrentFragment());

출력 :

D/MainActivity: FragOne

Tainy 의 답변에서 영감을 얻은 여기 2 센트가 있습니다. 대부분의 다른 구현에서는 거의 수정되지 않았습니다.

private Fragment getCurrentFragment() {
    FragmentManager fragmentManager = myActivity.getSupportFragmentManager();
    int stackCount = fragmentManager.getBackStackEntryCount();
    if( fragmentManager.getFragments() != null ) return fragmentManager.getFragments().get( stackCount > 0 ? stackCount-1 : stackCount );
    else return null;
}

교체 "myActivity"와 함께 "이"당신의 현재 활동 또는 활동에 사용 기준이됩니다.


findFragmentById()에서 호출되는 메소드가 있습니다 SupportFragmentManager. 나는 다음과 같은 활동 컨테이너에서 사용합니다 :

public Fragment currentFragment(){
    return getSupportFragmentManager().findFragmentById(R.id.activity_newsfeed_frame);
}

그것이 현재를 얻는 방법 Fragment입니다. 사용자 정의가 Fragment있고 Fragment그것이 무엇인지 확인 해야하는 경우 일반적으로 다음을 사용합니다 instanceof.

if (currentFragment() instanceof MyFrag){
    // Do something here
}

여기에 Kotlin을 사용하는 경우 :

var fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)

R.id.fragment_container발표 id장소는fragmentactivity

또는 더 나은 솔루션을 원한다면 :

supportFragmentManager.findFragmentById(R.id.content_main)?.let {
    // the fragment exists

    if (it is FooFragment) {
        // The presented fragment is FooFragment type
    }
}

코 틀린 방식;

val currentFragment = supportFragmentManager.fragments.last()

이것은 현재 조각을 얻는 간단한 방법입니다.

getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
  @Override public void onBackStackChanged() {
    currentFragment = fragmentManager.findFragmentById(R.id.content);
    if (currentFragment !=  null && (currentFragment instanceof LoginScreenFragment)) {
      logout.setVisibility(View.GONE);
    } else {
      logout.setVisibility(View.VISIBLE);
    }
  }
});

Sev의 답변 은 뒤로 버튼을 누르거나 백 스택을 변경하면 작동합니다.

그래도 약간 다른 것을했습니다. 기본 조각과 파생 조각에 백 스택 변경 리스너 설정이 있으며이 코드는 리스너에 있습니다.

Fragment f = getActivity().getSupportFragmentManager().findFragmentById(R.id.container);

if (f.getClass().equals(getClass())) {
    // On back button, or popBackStack(),
    // the fragment that's becoming visible executes here,
    // but not the one being popped, or others on the back stack

    // So, for my case, I can change action bar bg color per fragment
}

이것은 나를 위해 일한 것입니다. 나는 이것이 누군가에게 도움이되기를 바랍니다.

FragmentManager fragmentManager = this.getSupportFragmentManager();  
        String tag = fragmentManager
                    .getBackStackEntryAt(
                    fragmentManager
                    .getBackStackEntryCount() - 1)
                    .getName();
              Log.d("This is your Top Fragment name: ", ""+tag);

부모 활동에서 현재 Fragment 인스턴스를 얻는다면

findFragmentByID(R.id.container);

실제로 뷰에 채워진 조각의 현재 인스턴스를 가져옵니다. 나는 같은 문제가 있었다. 백 스택에 하나를 유지하면서 동일한 조각을 두 번로드해야했습니다.

다음 방법이 작동하지 않습니다. 태그가있는 조각 만 가져옵니다. 이 방법에 시간을 낭비하지 마십시오. 나는 그것이 그것을 사용하고 있다고 확신하지만 동일한 조각의 최신 버전을 얻는 것은 그중 하나가 아닙니다.

findFragmentByTag()

이 솔루션을 확인하십시오. 현재 조각을 얻는 것이 효과가있었습니다.

if(getSupportFragmentManager().getBackStackEntryCount() > 0){
        android.support.v4.app.Fragment f = 
         getSupportFragmentManager().findFragmentById(R.id.fragment_container);
        if(f instanceof ProfileFragment){
            Log.d(TAG, "Profile Fragment");
        }else if(f instanceof SavedLocationsFragment){
            Log.d(TAG, "SavedLocations Fragment");
        }else if(f instanceof AddLocationFragment){
            Log.d(TAG, "Add Locations Fragment");
        }

final FragmentManager fm=this.getSupportFragmentManager();
final Fragment fragment=fm.findFragmentByTag("MY_FRAGMENT");

if(fragment != null && fragment.isVisible()){
      Log.i("TAG","my fragment is visible");
}
else{
      Log.i("TAG","my fragment is not visible");
}

기본 활동에서 새 단편이 활동에 첨부되면 onAttachFragment (Fragment fragment) 메소드가 호출됩니다. 이 방법에서는 현재 조각의 인스턴스를 얻을 수 있습니다. 그러나 조각이 백 스택에서 튀어 나올 때 (즉, 맨 위 조각을 스택의 맨 위에 가져 오기 위해 뒤로 단추를 누를 때) onAttachFragment 메서드는 호출되지 않습니다. 여전히 활동 내에서 조각이 표시되면 기본 활동에서 트리거되는 콜백 메소드를 찾고 있습니다.


비슷한 문제가 발생하여 뒤로 키를 눌렀을 때 마지막으로 표시된 조각을 알고 싶었습니다. 나는 나를 위해 일한 매우 간단한 솔루션을 사용했습니다. 조각을 열 때마다 onCreate () 메서드에서 단일 톤에 변수를 설정합니다 ( "myFragment"를 조각 이름으로 바꿉니다)

MySingleton.currentFragment = myFragment.class;

변수는 싱글 톤에서 다음과 같이 선언됩니다.

public static Class currentFragment = null; 

그런 다음 onBackPressed ()에서 확인합니다.

    if (MySingleton.currentFragment == myFragment.class){
        // do something
        return;
    }
    super.onBackPressed();

super.onBackPressed ()를 호출해야합니다. "반환"후, 그렇지 않으면 앱이 백 키를 처리하여 내 경우에는 앱이 종료됩니다.


스크롤 된 조각의 경우 ViewPager 클래스의 인스턴스를 사용할 때 mVeiwPager가 있다고 가정하면 현재 조각 int 번호를 얻기 위해 mViewPager.getCurrentItem ()을 호출 할 수 있습니다.

MainLayout.xml에서

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context="unidesign.photo360.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="false"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:expanded="false">

        <android.support.v7.widget.Toolbar
            android:id="@+id/main_activity_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:title="@string/app_name">

        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>


    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </android.support.v4.view.ViewPager>
    
</android.support.design.widget.CoordinatorLayout>

MainActivity.kt에서

class MainActivity : AppCompatActivity() {
    
        lateinit var mViewPager: ViewPager
        lateinit var pageAdapter: PageAdapter
        
//      ...
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            
            pageAdapter = PageAdapter(supportFragmentManager)
            mViewPager = findViewById(R.id.view_pager)
//          ...
            }
            
        override fun onResume() {
          super.onResume()
          var currentFragment = pageAdapter.getItem(mViewPager.currentItem)
//         ...
          }


getSupportFragmentManager().findFragmentById(R.id.content_frame).getClass().getSimpleName();

글쎄, 나는 이것이이 질문에 대한 가장 직접적인 대답이라고 생각합니다. 이게 도움이 되길 바란다.


Kotlin 솔루션은 다음과 같습니다.

if ( this.getSupportFragmentManager().getBackStackEntryCount()>0 ) {
    var fgmt = this.getSupportFragmentManager().fragments[this.getSupportFragmentManager().getBackStackEntryCount()-1]
    if( fgmt is FgmtClassName ) {
        (fgmt as FgmtClassName).doSth()
    }
}

단순화 된 방법 :

with ( this.getSupportFragmentManager() ) {
    if ( getBackStackEntryCount()>0 ) {
        var fgmt = fragments[getBackStackEntryCount()-1]
        if ( fgmt is FgmtClassName ) {
            (fgmt as FgmtClassName).doSth()
        }
    }
}

아마도 가장 간단한 방법은 다음과 같습니다.

public MyFragment getVisibleFragment(){
    FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    for(Fragment fragment : fragments){
        if(fragment != null && fragment.getUserVisibleHint())
            return (MyFragment)fragment;
    }
    return null;
}

그것은 나를 위해 일했다


이러한 상황에서 이벤트 버스 ( Otto , EventBus 또는 RxJava Bus 등 )를 사용하는 것이 특히 편리합니다.

이 방법으로 현재 보이는 프래그먼트를 객체로 전달할 필요는 없지만 (그렇지만 수행 할 수는 있지만 더 긴 호출 체인으로 이어짐) 현재 보이는 프래그먼트에 대한 작업을 실행할 수 있습니다. 현재 보이는 조각을 알고 싶습니다.)

  1. 프래그먼트 라이프 사이클을 존중하고 적절한 시간에 이벤트 버스를 등록 / 등록 취소하십시오.
  2. 현재 보이는 프래그먼트를 알아야하고 일련의 작업을 실행해야하는 시점에서. 이벤트 버스로 이벤트를 촬영하십시오.

버스에 등록 된 모든 보이는 조각은 필요한 조치를 실행합니다.


조금 이상하지만 FragmentManager $ FragmentManagerImpl을 보았고 다음과 같이 작동합니다.

public static Fragment getActiveFragment(Activity activity, int index)
{
    Bundle bundle = new Bundle();
    String key = "i";
    bundle.putInt(key,index);
    Fragment fragment=null;
    try
    {
        fragment = activity.getFragmentManager().getFragment(bundle, key);
    } catch(Exception e){}
    return fragment;
}

첫 번째 활성 조각을 얻으려면 인덱스로 0을 사용하십시오.


public Fragment getVisibleFragment() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    if(fragments != null) {
        for (Fragment fragment : fragments) {
            if (fragment != null && fragment.isVisible())
                return fragment;
        }
    }
    return null;
}

이것은 나를 위해 작동합니다. 조각 목록을 반복하기 전에 null 검사를 수행해야합니다. 스택에 조각이로드되지 않는 시나리오가있을 수 있습니다.

반환 조각은 스택에 넣을 조각과 비교할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/9294603/how-do-i-get-the-currently-displayed-fragment



반응형