如何从 Presenter 访问 Fragment Manager(或 Hosting Activity)
How to Access the Fragment Manager (or the Hosting Activity) from the Presenter
我需要从演示者那里访问片段管理器(或 activity)。我怎样才能访问它?演示者本身是从另一个演示者调用的,而另一个演示者又是从片段中调用的。如何从演示者访问片段管理器或托管 activity?我需要实现一个接口吗?提前致谢。
public class EPGTitleRowPresenter extends Presenter {
private final static String TAG = EPGTitleRowPresenter.class.getSimpleName();
private Context mContext;
private static int sSelectedBackgroundColor;
private static int sDefaultBackgroundColor;
public EPGTitleRowPresenter(Context context) {
mContext = context;
}
private View.OnFocusChangeListener mOnFocusChangeListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
updateEPGTitleRowBackgroundColor(v, true);
}
else {
updateEPGTitleRowBackgroundColor(v, false);
}
}
};
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
VerticalGridView vgv = (VerticalGridView) v.getParent();
int pos = vgv.getSelectedPosition();
if (pos > 0) {
//TODO: mark programme for auto-switch
}
else {
//TODO: switch to channel
}
}
};
private static void updateEPGTitleRowBackgroundColor(View view, boolean selected) {
int color = selected ? sSelectedBackgroundColor : sDefaultBackgroundColor;
// Both background colors should be set because the view's background is temporarily visible
// during animations.
view.setBackgroundColor(color);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
EPGTitleRowView view = new EPGTitleRowView(parent.getContext()) {
@Override
public void setSelected(boolean selected) {
Log.i(TAG, "setSelected called");
super.setSelected(selected);
}
};
view.setMinimumWidth(parent.getWidth());
sDefaultBackgroundColor =
ContextCompat.getColor(parent.getContext(), android.R.color.transparent);
sSelectedBackgroundColor =
Color.parseColor("#66ffe680");
view.setFocusable(true);
view.setFocusableInTouchMode(true);
updateEPGTitleRowBackgroundColor(view, false);
view.setOnClickListener(mOnClickListener);
view.setOnFocusChangeListener(mOnFocusChangeListener);
return new ViewHolder(view);
}
@CallSuper
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
final Programme prog = (Programme) item;
ViewHolder vh = (ViewHolder) viewHolder;
vh.mProgrammeTitle.setText(prog.getTitle().get(0));
Date startDateTime = new Date(prog.getStart_utc() * 1000l);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
String strStartTime = sdf.format(startDateTime);
vh.mProgrammeStartTime.setText(strStartTime);
}
public class ViewHolder extends Presenter.ViewHolder {
public EPGTitleRowView mRootView;
public TextView mProgrammeTitle;
public TextView mProgrammeStartTime;
public ViewHolder(View view) {
super(view);
mRootView = (EPGTitleRowView) view;
mProgrammeTitle = (TextView) view.findViewById(R.id.programme_title);
mProgrammeStartTime = (TextView) view.findViewById(R.id.programme_start_time);
}
}
public class EPGTitleRowView extends FrameLayout {
public EPGTitleRowView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.epg_title_row, this);
}
}
}
如果您使用演示者,我假设您使用的是 MVP 模式。如果是这种情况,最好让您的代码尽可能远离 Android 组件(如 fragmentManager),以便更好地解耦。
我的建议是在视图中调用一个方法(假设视图是一个 Activity),并且演示者需要知道视图,因此您可以使用视图的接口(您可能正在使用)
像这样:
public interface MyView {
void methodToUseFragmentManager();
}
演示者需要知道它,所以它可能看起来像这样:
MyView view:
public EPGTitleRowPresenter (MyView view){
this.view = view;
}
void methodToUpdateView(){
view.methodToUseFragmentManager();
}
最后在您的 Activity 上实现该接口:
public class MyActivity extends AppCompatActivity implements MyView{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = new EPGTitleRowPresenter(this);
}
@Override
void methodToUseFragmentManager(){
// Here you can access the FragmentManager
}
}
我还注意到您的演示者获得了上下文,如上所述将事情分离并不是一个好主意。每当您需要访问上下文时,调用 View
中的方法
编辑
如果您有超过 1 个演示者,假设您有 2 个:parentPresenter 和 childPresenter,即 EPGTitleRowPresenter child
所以你的 parent 礼物应该是这样的:
MyView view:
EPGTitleRowPresenter childPresenter;
public ParentPresenter (MyView view){
this.view = view;
childPresenter = new EPGTitleRowPresenter(view);
}
和 child (EPGTitleRowPresenter) 与原始答案相同。
您的 activity 将如下所示:
public class MyActivity extends AppCompatActivity implements MyView{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = new ParentPresenter(this);
}
@Override
void methodToUseFragmentManager(){
// Here you can access the FragmentManager
}
}
我需要从演示者那里访问片段管理器(或 activity)。我怎样才能访问它?演示者本身是从另一个演示者调用的,而另一个演示者又是从片段中调用的。如何从演示者访问片段管理器或托管 activity?我需要实现一个接口吗?提前致谢。
public class EPGTitleRowPresenter extends Presenter {
private final static String TAG = EPGTitleRowPresenter.class.getSimpleName();
private Context mContext;
private static int sSelectedBackgroundColor;
private static int sDefaultBackgroundColor;
public EPGTitleRowPresenter(Context context) {
mContext = context;
}
private View.OnFocusChangeListener mOnFocusChangeListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
updateEPGTitleRowBackgroundColor(v, true);
}
else {
updateEPGTitleRowBackgroundColor(v, false);
}
}
};
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
VerticalGridView vgv = (VerticalGridView) v.getParent();
int pos = vgv.getSelectedPosition();
if (pos > 0) {
//TODO: mark programme for auto-switch
}
else {
//TODO: switch to channel
}
}
};
private static void updateEPGTitleRowBackgroundColor(View view, boolean selected) {
int color = selected ? sSelectedBackgroundColor : sDefaultBackgroundColor;
// Both background colors should be set because the view's background is temporarily visible
// during animations.
view.setBackgroundColor(color);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
EPGTitleRowView view = new EPGTitleRowView(parent.getContext()) {
@Override
public void setSelected(boolean selected) {
Log.i(TAG, "setSelected called");
super.setSelected(selected);
}
};
view.setMinimumWidth(parent.getWidth());
sDefaultBackgroundColor =
ContextCompat.getColor(parent.getContext(), android.R.color.transparent);
sSelectedBackgroundColor =
Color.parseColor("#66ffe680");
view.setFocusable(true);
view.setFocusableInTouchMode(true);
updateEPGTitleRowBackgroundColor(view, false);
view.setOnClickListener(mOnClickListener);
view.setOnFocusChangeListener(mOnFocusChangeListener);
return new ViewHolder(view);
}
@CallSuper
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
final Programme prog = (Programme) item;
ViewHolder vh = (ViewHolder) viewHolder;
vh.mProgrammeTitle.setText(prog.getTitle().get(0));
Date startDateTime = new Date(prog.getStart_utc() * 1000l);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
String strStartTime = sdf.format(startDateTime);
vh.mProgrammeStartTime.setText(strStartTime);
}
public class ViewHolder extends Presenter.ViewHolder {
public EPGTitleRowView mRootView;
public TextView mProgrammeTitle;
public TextView mProgrammeStartTime;
public ViewHolder(View view) {
super(view);
mRootView = (EPGTitleRowView) view;
mProgrammeTitle = (TextView) view.findViewById(R.id.programme_title);
mProgrammeStartTime = (TextView) view.findViewById(R.id.programme_start_time);
}
}
public class EPGTitleRowView extends FrameLayout {
public EPGTitleRowView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.epg_title_row, this);
}
}
}
如果您使用演示者,我假设您使用的是 MVP 模式。如果是这种情况,最好让您的代码尽可能远离 Android 组件(如 fragmentManager),以便更好地解耦。
我的建议是在视图中调用一个方法(假设视图是一个 Activity),并且演示者需要知道视图,因此您可以使用视图的接口(您可能正在使用)
像这样:
public interface MyView {
void methodToUseFragmentManager();
}
演示者需要知道它,所以它可能看起来像这样:
MyView view:
public EPGTitleRowPresenter (MyView view){
this.view = view;
}
void methodToUpdateView(){
view.methodToUseFragmentManager();
}
最后在您的 Activity 上实现该接口:
public class MyActivity extends AppCompatActivity implements MyView{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = new EPGTitleRowPresenter(this);
}
@Override
void methodToUseFragmentManager(){
// Here you can access the FragmentManager
}
}
我还注意到您的演示者获得了上下文,如上所述将事情分离并不是一个好主意。每当您需要访问上下文时,调用 View
中的方法编辑
如果您有超过 1 个演示者,假设您有 2 个:parentPresenter 和 childPresenter,即 EPGTitleRowPresenter child
所以你的 parent 礼物应该是这样的:
MyView view:
EPGTitleRowPresenter childPresenter;
public ParentPresenter (MyView view){
this.view = view;
childPresenter = new EPGTitleRowPresenter(view);
}
和 child (EPGTitleRowPresenter) 与原始答案相同。
您的 activity 将如下所示:
public class MyActivity extends AppCompatActivity implements MyView{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = new ParentPresenter(this);
}
@Override
void methodToUseFragmentManager(){
// Here you can access the FragmentManager
}
}