如何正确管理活动高度及其添加的片段的高度

时间:2016-05-15 20:00:14

标签: android android-fragments

我的片段有一个textview,其文本包含链接,每次单击链接时,我都会执行片段事务以添加同一片段的新实例。

为了进一步解释,我有一个托管fragmentA的ActivityA。

FragmentA从网络中提取文字。该文本包含链接。单击fragmentA中的链接时,对ActivityA的回调将启动一个新的FragmentA实例 再次获取另一个文本。

这些是我的代码:

ActivityA

public class ActivityA extends AppCompatActivity implements FragmentA.OnLinkClickedListener {

    private final String TAG = "ActivityA";
    Fragment mContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rock);

        String rock_id = getIntent().getStringExtra("rockId");
        Log.d(TAG,  rock_id);

        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

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

            fragment = new FragmentA();
            bundle.putString("rock_link", rock_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.rock_frame, fragment);
            ft.commit();
        }

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

    }

    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mContent != null) {
            getSupportFragmentManager().putFragment(outState, "mContent", mContent);
        }
    }
    @Override
    public void OnLinkClicked(String link) {
        Log.d(TAG, "The activity got the url and it is " + link);
        Bundle bundle = new Bundle();
        Fragment fragment;

        fragment = new FragmentA();
        bundle.putString("rock_link", link);
        fragment.setArguments(bundle);

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        //ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right, android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        ft.addToBackStack(null);
        //ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.add(R.id.rock_frame, fragment);
        ft.commit();
    }
}

FragmentA

public class FragmentA extends Fragment {

    OnLinkClickedListener mLinkClickedListener = sLinkCallbacks;

    private AlertDialog internetDialog;
    private AlertDialog sthWrongAlert;
    private String url;

    private String rockData;

    private final String TAG = "FragmentA";
    protected com.nostra13.universalimageloader.core.ImageLoader mImageLoader;


    TextView rockContent;
    private String rock_content;

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView called");
        url = getArguments().getString("rock_link");
        Log.d(TAG, "Rock url is " + url);
        view =  inflater.inflate(R.layout.fragment_details, container, false);
        showDialog();
        sthWrongDialog();


        rockContent = (TextView) view.findViewById(R.id.drock_content);


        DisplayImageOptions defaultoptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity())
                .defaultDisplayImageOptions(defaultoptions)
                .writeDebugLogs()
                .build();


        mImageLoader = com.nostra13.universalimageloader.core.ImageLoader.getInstance();
        mImageLoader.init(config);

        if (savedInstanceState != null) {


            rockData = savedInstanceState.getString("rockData");
            if (rockData != null) {
                parseHtml(rockData);
            } else if (NetworkCheck.isAvailableAndConnected(getActivity())){
                loadRock();
            }



        } else {
            if (NetworkCheck.isAvailableAndConnected(getActivity())) {
                //Calling method to load rocks
                loadRock();
            } else {
                internetDialog.show();
            }
        }
        return view;
    }


    public interface OnLinkClickedListener {
        public void OnLinkClicked (String link);
    }

    private static OnLinkClickedListener sLinkCallbacks = new OnLinkClickedListener() {
        @Override
        public void OnLinkClicked(String link) {

        }
    };


    private void showDialog() {
        internetDialog = new AlertDialog.Builder(getActivity())
                ...
    }

    private void sthWrongDialog() {
        sthWrongAlert = new AlertDialog.Builder(getActivity())
                ...
    }




    private void loadRock() {
        Log.d(TAG, "loadRock called");

        final ProgressBar progressBar;
        progressBar = (ProgressBar) view.findViewById(R.id.progress_circle);
        progressBar.setVisibility(View.VISIBLE);

        Log.d(TAG, "You clicked rock id " + url);

        StringRequest stringRequest = new StringRequest(url,
                new Response.Listener<String>() {
                    // The usual codes for volley string request
                    //parseHtml() is called in onResponse
                });

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

        //Adding request queue
        requestQueue.add(stringRequest);


    }

    private void parseHtml(String response) {
        Log.d(TAG, "parsinghtml");
        Document document = Jsoup.parse(response);
        rock_content = document.select("div.entry-content").first().html();

        rockContent.setVisibility(View.VISIBLE);

    }

    protected void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span)
    {
        int start = strBuilder.getSpanStart(span);
        int end = strBuilder.getSpanEnd(span);
        int flags = strBuilder.getSpanFlags(span);
        ClickableSpan clickable = new ClickableSpan() {
            public void onClick(View view) {
                // Do something with span.getURL() to handle the link click...
                Log.e(TAG, "on click" + span.getURL());
                String clickedLink = span.getURL();
                mLinkClickedListener.OnLinkClicked(clickedLink);

            }
        };
        strBuilder.setSpan(clickable, start, end, flags);
        strBuilder.removeSpan(span);
    }

    protected void setTextViewHTML(TextView text, String html) {
        CharSequence sequence = Html.fromHtml(html, new UILImageGetter(rockContent, getActivity()), null);
        SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);
        URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class);
        for(URLSpan span : urls) {
            makeLinkClickable(strBuilder, span);
        }
        text.setText(strBuilder);
        text.setMovementMethod(LinkMovementMethod.getInstance());
    }


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mLinkClickedListener = (OnLinkClickedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnLinkClickedListener");
        }
    }
}

FragmentA的布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:background="@android:color/white">

    <RelativeLayout

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        tools:context=".ActivityA">


        <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/progress_circle"
            android:visibility="gone"
            android:layout_centerInParent="true"/>


        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/dviewbottom"
            android:hint="@string/main_body"
            android:textColorLink="@color/textlink"
            android:visibility="gone"
            android:id="@+id/drock_content"
            android:layout_margin="5dp"/>

    </RelativeLayout>


</FrameLayout>

ActivityA的布局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scrollView"
    android:fillViewport="true">

    <FrameLayout
        android:id="@+id/rock_frame"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>


</ScrollView>

就像我上面写的那样,当我点击FragmentA里面的rockContent中的链接时,ActivityA会启动一个新的FragmentA实例。

问题是这个新的FragmentA实例仍然具有前实例的高度。在加载数据之后,底部有一个空白区域,或者文本被截断,具体取决于前一个实例的大小。

为了进一步说明,在将数据加载到新片段之前,我可以向上和向下滚动,因为高度仍然是片段的旧实例的高度。

请问我该怎么说?即,使片段的每个新实例具有我在布局中设置的电话屏幕的高度?

修改

如果我在FragmentA布局的FrameLayout中设置android:layout_width="wrap_content",问题就解决了,即没有额外的空格或截断。这样做的问题是进度条不再以屏幕为中心。它位于ActionBar的正下方。

0 个答案:

没有答案