Android Fragment實現分屏

來源:互聯網
上載者:User

標籤:

在項目中碰到一個問題,新開發一個平板APP,項目要求是把原來的一個手機端APP放在項目左側顯示,右側添加新加的功能。

首先想到了Fragment,以前做過Fragment的一些簡單的Demo,但是都沒有應用到項目中去過,這次倒是好好的運用了一把。

首先,考慮到已經存在的手機端APP代碼繁多,且不怎麼規範(代碼裡面大概有二三十個Activity檔案,且命名及其他方面都極其不規範),所以就想不要在原來代碼上太多的重構,在看了一篇文章之後,慢慢的有了些思路。(http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=404548816&idx=1&sn=f042037982ed2e74210c57edf864e31a&scene=0#wechat_redirect)這篇文章也說了些重構的問題,不過看了之後覺得不適合自己的,只是很好的為自己提供了一個思路。於是就自己寫了個Demo。

Demo的結構是這樣的

我先寫了一個BasePadFragment,讓所有的Fragment去實現這個基類,從而統一實現一些共通的方法。由於是Demo所以基類裡面只提供了一個Fragment的跳轉方法

BasePadFragment.java

import android.app.Fragment;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.content.Context;import android.os.Bundle;import android.support.v4.app.FragmentActivity;import java.util.List;/** * Created by Bob on 2016/4/11. */public class BasePadFragment extends Fragment{    public Context mContext;    public void startToFragment(Context context,int container,Fragment newFragment){        FragmentManager manager = getFragmentManager();        FragmentTransaction transaction = manager.beginTransaction();        transaction.replace(container,newFragment);        transaction.addToBackStack(context.getClass().getName());        transaction.commit();    }}

方法裡面的參數分別是context:上下文;container:Fragment的容器;newFragment:要跳轉到的Fragment的對象;

再看看方法體裡面,首先獲得Frament的一些主要操作對象FragmentManager/FragmentTransaction然後利用transaction進行fragment的置換,再將當前fragment進行壓棧操作,這一步非常關鍵,因為如果不添加的話,按返回按鈕是不能回到上一個fragment的。最後是提交commit方法。

主介面activity比較簡單就是簡單的一個onCreatView再後面的源碼裡面可以查看。

再來說主介面的布局:

activity_index.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:baselineAligned="false">    <FrameLayout        android:id="@+id/layout_container"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="4">        <fragment            android:id="@+id/left_fragment"            android:name="com.sailing.www.multiscreendemo.fragment.LeftFragment"            android:layout_width="match_parent"            android:layout_height="match_parent" />    </FrameLayout>    <View        android:layout_width="5dp"        android:layout_height="match_parent"        android:background="#000000" />    <FrameLayout        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="6">        <fragment            android:id="@+id/right_fragment"            android:name="com.sailing.www.multiscreendemo.fragment.RightFragment"            android:layout_width="match_parent"            android:layout_height="match_parent" />    </FrameLayout></LinearLayout>

   可以看到我在主介面裡面添加了兩個fragment;將這兩個fragment水平的放在一個LinearLayout裡面。在放入的時候切記要將fragment外麵包裹一層parentView我用的是FrameLayout,因為在跳轉的時候要針對container進行跳轉,所以要在這個parentView就相當於是一個容器將fragment放在裡面,所有的頁面的替換都是在這個容器內進行操作。且這個容器一定要添加id,否則會報找不到view的錯誤。

介面效果是這樣的。

左側的Fragment 

LeftFramgment:

import android.app.Fragment;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.os.Bundle;import android.os.PersistableBundle;import android.support.annotation.Nullable;import android.support.v4.app.FragmentActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.ListView;import android.widget.TextView;/** * Created by Bob on 2016/4/5. */public class LeftFragment extends BasePadFragment implements View.OnClickListener{    private Button btnNextPage,btnNextAnother;    private RecyclerView mRecyclerView;    private HorizontalListAdapter horizontalListAdapter;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.layout_left, null);        btnNextPage = (Button)view.findViewById(R.id.btn_next_page);        btnNextAnother = (Button)view.findViewById(R.id.btn_next_another);        btnNextPage.setOnClickListener(this);        btnNextAnother.setOnClickListener(this);        mRecyclerView = (RecyclerView)view.findViewById(R.id.recycler_view);        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);        // 設定布局管理器        mRecyclerView.setLayoutManager(layoutManager);        String[] dataset = new String[100];        for (int i = 0; i < dataset.length; i++) {            dataset[i] = "item" + i;        }        RecyclerAdapter mAdapter = new RecyclerAdapter(dataset);        mRecyclerView.setAdapter(mAdapter);        return view;    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.btn_next_page:                AnotherFragment anotherFragment  = new AnotherFragment();                startToFragment(getActivity(), R.id.layout_container, anotherFragment);                break;            case R.id.btn_next_another:                NextAnotherFragment nextAnotherFragment = new NextAnotherFragment();                startToFragment(getActivity(),R.id.layout_container,nextAnotherFragment);                break;            default:                break;        }    }    public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {        private String[] mDataset;              public RecyclerAdapter(String[] dataset) {            mDataset = dataset;        }        public  class ViewHolder extends RecyclerView.ViewHolder {            public TextView mTextView;                       public ViewHolder(View itemView) {                super(itemView);                mTextView = (TextView) itemView;            }        }             @Override        public int getItemCount() {            return mDataset.length;        }      android.support.v7.widget.RecyclerView.Adapter#onBindViewHolder(android.support.v7.widget.RecyclerView.ViewHolder,         *      int)         */        @Override        public void onBindViewHolder(ViewHolder holder, int position) {            holder.mTextView.setText(mDataset[position]);        }      android.support.v7.widget.RecyclerView.Adapter#onCreateViewHolder(android.view.ViewGroup,         *      int)         */        @Override        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {            View view = View.inflate(parent.getContext(),                    android.R.layout.simple_list_item_1, null);            ViewHolder holder = new ViewHolder(view);            return holder;        }    }}

 因為後續還在這個Demo裡面進行了另外一些測試,所以有一些雜的控制項在裡面。我們只看代碼的主要模組,就是按鈕的操作,在點擊了按鈕之後我跳轉到了另外的Framgment,直接用父類的startToFragment()方法,操作起來還是很簡單的。

在第二個頁面我在這裡進行了參數的傳遞和擷取。

AnotherFragment:

import android.app.Fragment;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.Spinner;/** * Created by Bob on 2016/4/5. */public class AnotherFragment extends BasePadFragment implements View.OnClickListener {    private Button btnToThirdPage;    private EditText mEdtName;    private Spinner mSpinText;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.layout_another, null);        mContext = getActivity();        btnToThirdPage = (Button) view.findViewById(R.id.btn_another);        mEdtName = (EditText)view.findViewById(R.id.edt_name);        mSpinText = (Spinner)view.findViewById(R.id.spi_text);        String [] textArray = getResources().getStringArray(R.array.text);        ArrayAdapter<String> textAdapter = new ArrayAdapter<String>(mContext,R.layout.myspinner,textArray);        textAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);        mSpinText.setAdapter(textAdapter);        btnToThirdPage.setOnClickListener(this);        return view;    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn_another:                ThirdFragment thirdFragment = new ThirdFragment();                String name = mEdtName.getText().toString();                Bundle bundle = new Bundle();                if(name != null){                    bundle.putString("name",name);                }                bundle.putString("password","12345678");                thirdFragment.setArguments(bundle);                startToFragment(getActivity(), R.id.layout_container, thirdFragment);                break;            default:                break;        }    }}

  同樣在按鈕的點擊事件中,我利用Bundle進行資料的傳遞,使用起來也是挺簡單的。在第三個介面進行資料的擷取也挺簡單。

ThirdFragment:

import android.app.Fragment;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;/** * Created by Bob on 2016/4/11. */public class ThirdFragment extends Fragment {    private TextView tvName;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.layout_third_fragment, null);        tvName = (TextView)view.findViewById(R.id.tv_name);        Bundle bundle  = getArguments();        String name =bundle.getString("name");        String password = bundle.getString("password");        if(null != name){            tvName.setText(name+"    "+password);        }        return view;    }}

  簡單的思路,但是在引用到項目裡面去的時候又發現了一個比較匪夷所思的問題,那就是儘管進行了fragment的跳轉,但是上一個Fragment好像並沒有被遮蓋,就是說在當前的fragment還能操作上一個fragment。這個就有點坑爹了,後面在找了好些資料之後終於把問題解決。下面是最終的BasePadFragment的StartToFragment方法。

/**     * 跳轉到另外一個fragment的方法     * @param  currentFragment 當前fragment     * @param container:當前fragment所處的容器     * @param newFragment 下一個fragment     * */    public void startToFragment(Fragment currentFragment,Context context,int container,Fragment newFragment){        if(currentFragment != newFragment){            manager = getFragmentManager();            transaction = manager.beginTransaction();            if(! newFragment.isAdded()){                transaction.hide(currentFragment).add(container,newFragment);                transaction.addToBackStack(context.getClass().getName());                transaction.commit();            }else{               transaction.hide(currentFragment).show(newFragment);                transaction.addToBackStack(context.getClass().getName());                transaction.commit();            }        }    }

  這樣就很好的處理了上一個Fragment不能被遮蓋的問題。處理的邏輯是這樣,先判斷新的fragment是否被add了進來如果沒有的話就hide掉上面的fragment,再把新的fragmentadd進來,如果add進來了就直接hide掉上一個fragment,直接壓棧並提交。

 源碼地址:https://github.com/bobLion/MultiScreenDemo

Android Fragment實現分屏

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.