【问题标题】:Hide/Show Button in Fragment from Activity从活动中隐藏/显示片段中的按钮
【发布时间】:2016-07-22 06:18:49
【问题描述】:

我试图在 Activity 的片段中隐藏/显示按钮,但它给了我以下异常。

android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能接触其视图。

家庭活动

 public class HomeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        CategoryFragment frag=(CategoryFragment) activity.getSupportFragmentManager() 
                                  .findFragmentByTag("cat_frag");
        Button newDesigns= (Button) frag.getView().findViewById(R.id.new_designs);
        newDesigns.setVisibility(View.VISIBLE);
     }
 }

类别片段

 public class CategoryFragment extends Fragment{
    Button newDesigns;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_category, null);
        newDesigns= (Button) v.findViewById(R.id.new_designs);
   }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#CCCCCC">

    <TextView
        android:id="@+id/list_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/shape_logo_bg"
        android:gravity="center"
        android:padding="5dp"
        android:textColor="@android:color/white"
        android:textSize="18sp" />

    <Button
        android:id="@+id/new_designs"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/list_name"
        android:background="@color/edit_button_color"
        android:padding="10dp"
        android:text="@string/new_designs"
        android:textColor="@color/btn_text_color"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="5dp"
        android:visibility="gone"
        />
</RelativeLayout>

代码太大,无法在此处发布。这就是为什么我只发布了我发现问题的代码。

我能够获得 newDesigns BUTTON 实例。令我震惊的是,如果尝试使用按钮实例 (VISIBLE/GONE),它会给我上述异常。

感谢您的帮助。

【问题讨论】:

标签: android android-layout android-fragments


【解决方案1】:

当您直接在 Activity 中时,您不应该使用 Fragment 的视图。您将不知道视图的状态是什么,这可能会导致您甚至无法想到的问题(相信我,我遇到了很多)。要与活动的视图交互,请创建一个界面:

public interface AccessFragmentViews{
  public void setVisibilityForButton(boolean bool);
  //any other methods that you need
}

现在在片段类中实现它并覆盖该方法。

class YourFragment implements AccessFragmentViews{

. 
.

    public void serVisibilityForButton(boolean shouldHide){
       if(shouldHide){
           yourButton.setVisibility(View.GONE);
       }else{
           yourButton.setVisibility(View.VISIBLE);
       }
    }
}

现在您可以使用此界面与活动中的片段视图安全地交互。在这样做之前确保片段是活动的;)访问孩子的视图很容易出现 WindowLeakedExceptions 和非法状态异常

在活动中使用如下:

您可以通过标签找到片段引用或使用您用于创建片段的引用来获取片段引用

//注意:从活动中访问片段视图是非常危险的

//first the alive check then the logic 

if(yourFragmentReference!=null){
((AccessFragmentViews)yourFragmentReference).setVisibilityForButton(true);// or false if you want to make it visible
}

【讨论】:

  • 据我了解他的问题,他想更改片段视图,而不是活动视图
  • 哎呀...颠倒顺序然后大声笑。 @MohammedAtif 谢谢你:)
  • 我猜,倒序实现起来有点棘手,你需要通过它的标签访问片段来调用方法。在您的情况下,接口绝对可以工作,但反向几乎没有危险。
  • @MohammedAtif 两者都很危险。我检查了他拥有的片段引用,但这不会让他免于所有问题。好吧,他想要这个,我还能做什么哈哈:D
【解决方案2】:

在你的片段类中添加一个方法

public void changeButtonVisibility(boolean visibility){
  if(visibility){
    newDesigns.setVisibility(View.VISIBLE);
  }else{
    newDesigns.setVisibilty(View.GONE);
  }
}

在你的活动课上

添加这一行

 public class HomeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        CategoryFragment frag=(CategoryFragment) activity.getSupportFragmentManager() 
                                  .findFragmentByTag("cat_frag");
        frag.changeButtonVisibility(true);
     }
 }

【讨论】:

  • 这将在不需要时保持不必要的引用。如果片段被破坏,应用程序也会崩溃。
  • 这只是一个例子,有几种访问活动片段的方法,如using tag referenceusing weak referencesusing variable reference,对于这个特定的例子,这个最适合。
猜你喜欢
  • 2019-10-23
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 1970-01-01
相关资源
最近更新 更多