无法从主机活动中访问片段中的变量

时间:2016-06-02 17:49:16

标签: android android-fragments

在我的片段中,我从网络中获取一个字符串,我希望托管活动能够获取此字符串,并在后台更改时使用它来设置它的操作栏的副标题。 我关注this answer并使用第三个选项。

这是我的代码:

匹配活动

public class Match extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener{


    public String matchTitle



    public String getMatchTitle() {
        return matchTitle;
    }

    public void setMatchTitle(String matchTitle) {
        this.matchTitle = matchTitle;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

    //The usuals

    if (savedInstanceState == null) {
                Bundle bundle = new Bundle();
                Fragment fragment;

                fragment = new DetailsFragment();
                bundle.putString("match_link", news_id);
                fragment.setArguments(bundle);

                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                ft.setCustomAnimations(android.R.anim.slide_out_right, android.R.anim.slide_in_left, android.R.anim.slide_out_right, android.R.anim.slide_in_left);
                ft.add(R.id.match_frame, fragment);
                ft.commit();
            }

            if (savedInstanceState != null) {
                mContent = getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
            }
    }

    ....
    @Override
        public void onBackStackChanged() {
            String subtitle = getMatchTitle();
            mToolbar.setSubtitle(subtitle);
        }

        ...

DetailsFragment

public class DetailsFragment extends Fragment {

public DetailsFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.d(TAG, "onCreateView called");
    //The usuals
  }

        private void  getMatch() {
    Log.d(TAG, "getMatch called");
    String matchJson = GET_URL + matchID;
    JsonObjectRequest matchDetails = new JsonObjectRequest(Method.GET, matchJson, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.d(TAG, "onResponse for getMatch called");
                    parseJson(response);
                    mainMatch = response;
                    if (progressBar != null) {
                        progressBar.setVisibility(View.GONE);
                    }
                }
            },
            new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.d(TAG,  "onErrorResponse for getMatch called");
            if (progressBar != null) {
                progressBar.setVisibility(View.GONE);
            }
            if (sthWrongAlert != null) {
                sthWrongAlert.show();
            }
        }
    });


    //Creating requestqueue
    RequestQueue requestQueue = Volley.newRequestQueue(getActivity());

    //Adding request queue
    requestQueue.add(matchDetails);
}

private void parseJson(JSONObject object) {
    Log.d(TAG, "Parsing Json");
    try {
        final String title = String.valueOf(Html.fromHtml(object.getString("title")));
        matchTitle.setText(title);

            Match match = new Match();
            match.setMatchTitle(title);


    } catch (JSONException w) {
        w.printStackTrace();

    }
}

注意我知道我可以轻松地从片段中设置字幕,但我不想这样做。我只是想确保我可以从它的主机活动中访问片段中的变量。

2 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是在Fragment中定义接口,并让活动实现接口。例如:

public class DetailsFragment {
    public interface OnTitleChangedListener {
        void onTitleChanged(String newTitle);
    }

    private OnTitleChangedListener mListener;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mListener = (OnTitleChangedListener) context;
        // TODO ensure instanceof OntTitleChangeListener
    }
}

然后,在您的齐射onResponse回调中,请致电mListener.onTitleChanged(newTitle)以将更改传达给活动。您的活动代码可能如下所示:

public class MatchActivity implements DetailsFragment.OnTitleChangedListener {
    @Override
    public void onTitleChanged(String newTitle) {
         mToolbar.setSubtitle(newTitle);
    }

答案 1 :(得分:0)

直接从活动中的片段访问变量会在片段和宿主活动之间引入强耦合。我建议使用诸如otto,http://square.github.io/otto/之类的通信库来处理这两者之间的通信。您可以注册活动以收听SubtitleChangeEvent,然后在需要反映字幕更改时从片段中触发此事件。