代码之家  ›  专栏  ›  技术社区  ›  Andromeda

StartActivityForResult不处理片段

  •  -1
  • Andromeda  · 技术社区  · 8 年前

    我有一个片段作为底部导航的一部分。在片段中,我有一个按钮来选择图像并在recyclerview中显示。

    我正在处理来自的此按钮的单击事件 onBindViewHolder() 调用fragment类中的方法,如下所示:

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof TrendingHeaderViewHolder){
            ((TrendingHeaderViewHolder) holder).cameraShareIV.setOnClickListener( view -> {
                TrendingFragment.newInstance().selectImage(); // this method is created in fragment class but called here in adapter
            });
        } else if (holder instanceof TrendingItemsViewHolder){
            TestTrends tre = trendsList.get(position - 1);
            Picasso.with(context)
                    .load(tre.getTestImage())
                    .placeholder(R.drawable.default_profile_photo)
                    .into(((TrendingItemsViewHolder) holder).testImgView);
        }
    }
    

    在片段中,方法如下所示:

    public void selectImage() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        startActivityForResult(intent, GAL_REQ_CODE);
        //context.startActivityForResult(intent, GAL_REQ_CODE); // tried with Activity and Context but still crashes
    }
    

    只要单击按钮,应用程序就会崩溃。以下是logcat中的错误:

    java.lang.IllegalStateException: Fragment TrendingFragment{171d0a0} not attached to Activity
       at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:1026)
       at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:1017)
       at base.android.com.thumbsapp.UI.Fragments.TrendingFragment.selectImage(TrendingFragment.java:120)
       at base.android.com.thumbsapp.Adapters.TrendingAdapter.lambda$onBindViewHolder$0$TrendingAdapter(TrendingAdapter.java:59)
       at base.android.com.thumbsapp.Adapters.TrendingAdapter$$Lambda$0.onClick(Unknown Source)
       at android.view.View.performClick(View.java:5690)
       at android.view.View$PerformClick.run(View.java:22693)
       at android.os.Handler.handleCallback(Handler.java:836)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loop(Looper.java:203)
       at android.app.ActivityThread.main(ActivityThread.java:6269)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
    

    下面是我的活动,其中包含底部导航片段:

    private final BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = item -> {
        FragmentTransaction ft = null;
        switch (item.getItemId()) {
            case R.id.navigation_home:
                viewpager.setCurrentItem(0);
                ft = getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fragContainer, new HomeFragment());
                ft.commit();
                return true;
            case R.id.navigation_trending:
                ft = getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fragContainer, new TrendingFragment());
                ft.commit();
                viewpager.setCurrentItem(2);
                return true;
            case R.id.navigation_chats:
                ft = getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fragContainer, new ChatsFragment());
                ft.commit();
                viewpager.setCurrentItem(3);
                return true;
            case R.id.navigation_profile:
                ft = getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fragContainer, new ProfileFragment());
                ft.commit();
                viewpager.setCurrentItem(4);
                return true;
            case R.id.navigation_search:
                ft = getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fragContainer, new SearchFragment());
                ft.commit();
                viewpager.setCurrentItem(1);
                return true;
        }
        return false;
    };
    

    以及布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="base.android.com.thumbsapp.UI.Activities.MainActivity">
    
    <android.support.v4.view.ViewPager
        android:id="@+id/fragments"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_above="@+id/navigation"/>
    
    <FrameLayout
        android:id="@+id/fragContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_above="@+id/navigation"/>
    
    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        app:itemBackground="@android:color/white"
        app:itemIconTint="@color/nav_bar_behave"
        app:itemTextColor="@color/nav_bar_behave"
        app:menu="@menu/navigation"
        android:layout_alignParentBottom="true"/>
    

    有人能解释一下为什么应用程序会崩溃吗?

    1 回复  |  直到 8 年前
        1
  •  0
  •   Bhagat    8 年前

    为什么应用程序会崩溃? 因为您的片段没有附加到任何活动。

    您应该在片段中实现一个监听器,以便在单击事件时从viewHolder调用。

    在适配器类中,定义一个接口

    public interface OnItemClickListener {
            void onItemClick();
    }
    
    while initializing your adapter class with listener implementation
    
    public Adapter(OnItemClickListenerener listener){
    this.listener = listener;
    }
    
    inside your view-holder:
    
    viewHolder.itemView..setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
    listener.onItemClick();}
    }
    

    最后,在封闭的活动中实现这个接口,然后让片段调用所需的方法。

    此外,您应该将onItemClick侦听器事件代码从onBindViewHolder移动到view holder

    推荐文章