的一个片段

问题描述:

提供的说法正确的做法我有一个这样的类:的一个片段

public Class Row { 
    private int data = 0; 
    private View.OnClickListener callback = null; 

    public void setData(int a) { data = a; } 
    public void setOnClickListener(View.OnClickListener i) { callback = i; } 
} 

而且我喜欢来提供这种类的一个实例的片段。考虑到成员界面,我不能序列化或包裹这个类,并通过setArgument()发送它。

对于将此课程提供给我的片段,您有什么建议?我想起了3种方法,但我不知道什么是更好的:

1,提供一流的通过一个设置功能:

Myfrag frag = new Myfrag(); 
Row r = new Row(); 
r.setOnClickListener(this); 
frag.setRow(r); 
getSupportFragmentManager().beginTrasaction().add(R.id.containder_id, frag).commit(); 

有些人反对使用这种方法,因为它似乎,这种方法可能会失败Fragment娱乐。

通过回调接口 在这种情况下活性

2-简化证明类提供了用于Fragment返回类的接口:

public class MyActivity extend Activity implements Myfrag.OnGetRow{ 
    private Row mRow = null; 
    ... 

    public createFragment() { 
     Myfrag frag = new Myfrag(); 
     mRow = new Row(); 
     mRow.setOnClickListener(this); 
     getSupportFragmentManager().beginTrasaction().add(R.id.containder_id, frag).commit(); 
    } 

    public Row getRow() { 
     return mRow; 
    } 
} 

而在Fragment

public class MyFrag extend Fragment { 
    ... 
    public interface OnGetRow { 
     public Row getRow(); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 

     OnGetRow mCallback = null; 

     try { 
      mCallback = (OnGetRow) activity; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() 
       + " must implement OnHeadlineSelectedListener"); 
     } 

     mRow = mCallback.getRow(); 
    } 
} 

3-只需提供一个公共功能进行活动,并在FragmentonAttach()中调用它。

你对这个问题有何建议?

+0

嗯......因为你传递了一些其他回调函数的对象......这听起来很奇怪。 也许您应该重新考虑代码中的架构变更。 如果没有,也许你可以尝试Dagger2注入框架。 –

+0

@BozicNebojsa不,这并不奇怪。我正在编写一个设置库。每个类的实例(与此类似,但更复杂)为我的设置提供一个项目。这些成员接口用于处理主活动中设置项的点击。 – Afshin

+0

可能的[实例化新的Android片段的最佳实践]的副本(http://*.com/questions/9245408/best-practice-for-instantiating-a-new-android-fragment) –

在我的知识中,更好的方法是将Row设置为可串行化并设置Row的实例,并将bundle设置为期望Fragment的参数,重新创建后,您可以使用函数getArguments()在onResume()方法中获取该bundle。这样你的数据将会持续存在。

+0

这种方法在这里不适用,因为接口是一个类成员变量。这是一个小课堂,但实际上,你可能在课堂上有几个复杂的自定义接口。 – Afshin

+0

为什么不呢,即使接口是一个类成员变量,你也可以这样做。 –

在我看来,最好的方法是在这个例子中,我已经使用Dart liblary来减少片段中的代码;

public class MyFragment extends Fragment { 

    private static final String FIRST_PARAM_KEY = "KEY1"; 
    private static final String SECOND_PARAM_KEY = "KEY2"; 

    @InjectExtra(FIRST_PARAM_KEY) 
    Integer firstParam; 
    @InjectExtra(SECOND_PARAM_KEY) 
    String SecondParam; 

    public static MyFragment newInstance(Integer param1, String param2) { 
     Fragment fragment = new MyFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(FIRST_PARAM_KEY, param1); 
     args.putString(SECOND_PARAM_KEY, param2); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Dart.inject(this, getArguments()); 
    } 
} 

无论何时您想要创建新片段,请使用:Fragment fragment = MyFragment.newInstance(123, "text")。记住如果你想传递对象,那个对象必须实现Parcelable

最好的方法是将你的数据放入bundle中,并将setArgument放入片段中。这里是一个例子 - 假设我有一个类UserModel的对象传递给UserFragment。

public class UserModel implements Parcelable{ 
    int id; 
    String name; 
    String profilePic; 

    protected UserModel(Parcel in) { 
     id = in.readInt(); 
     name = in.readString(); 
     profilePic = in.readString(); 
    } 

    public static final Creator<UserModel> CREATOR = new Creator<UserModel>() { 
     @Override 
     public UserModel createFromParcel(Parcel in) { 
      return new UserModel(in); 
     } 

     @Override 
     public UserModel[] newArray(int size) { 
      return new UserModel[size]; 
     } 
    }; 

    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     dest.writeInt(id); 
     dest.writeString(name); 
     dest.writeString(profilePic); 
    } 
} 
在UserFragement

现在这样做:

public class UserFragment extends Fragment { 
    private UserModel userModel; 
    private String userStr; 
    public static Fragment getInstance(UserModel userModel, String userStr) { 
     Bundle bundle = new Bundle(); 
     bundle.putParcelable("USER_DATA", userModel); 
     bundle.putString("USER_STR", userStr); 
     UserFragment userFragment = new UserFragment(); 
     userFragment.setArguments(bundle); 
     return userFragment; 
    } 

    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if(getArguments() != null){ 
      Bundle bundle = new Bundle(); 
      userModel = bundle.getParcelable("USER_DATA"); 
      userStr = bundle.getString("USER_STR"); 
     } 
    } 
} 

现在使用newInstance方法创建片段的新对象。

希望它能帮助你:)

+0

所有样本像你的和下一个答案都使用简单的'Parcelable'或'Serializable'成员变量(在你的情况int和String)。我知道我可以做到这一点。但我的问题是那些接口。如果你的一个类的成员是'View.OnClickListener'接口,你将如何做到这一点? – Afshin

+0

我相信你只想发送数据到片段,没有别的。只是还没有确认,为什么你想传递你的clickListener对象到片段。 – Neo

+0

我描述了为什么我发送了这个监听者对之前重播的评论。此侦听器在活动中提供与此类的实例相关的处理点击。我需要针对不同的类实例拥有不同的侦听器,因此我将其添加为类成员变量,并且需要为它提供片段。 – Afshin