簡體   English   中英

將數據從片段傳遞到另一個片段。 片段未附加到上下文

[英]Passing data from fragment to another fragment. Fragment not attached to a context

將數據從片段傳遞到另一個片段時遇到問題。

錯誤:

原因:java.lang.IllegalStateException:片段FragmentBayar {5cd96b2}未附加到上下文。 在android.support.v4.app.Fragment.requireContext(Fragment.java:614)在android.support.v4.app.Fragment.getResources(Fragment.java:678)在android.support.v4.app.Fragment.getString (Fragment.java:700)在com.kensai.appkasir.fragment.FragmentBayar $ Companion.newInstance(FragmentBayar.kt:45)在com.kensai.appkasir.FragmentActivity.onCreate(FragmentActivity.kt:55)在android.app。 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)上的Activity.performCreate(Activity.java:6303)android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2376)

這是我的片段

class FragmentBayar : Fragment(){
// order information
private lateinit var order: Orders

// data of menu before send
private var editList = ArrayList<EditQuantity>()
private lateinit var dataEditAdapter: EditQuantityAdapter

// data of menu after send
private var progressList = ArrayList<ProgressAntar>()
private lateinit var dataProgressAdapter: ProgressAntarAdapter

companion object {
    fun newInstance(order: Orders): FragmentBayar {
        val fragment = FragmentBayar()

        val bundle = Bundle()
        bundle.putParcelable(fragment.getString(R.string.key_pass_order), order)
        fragment.arguments = bundle
        return fragment
    }
}

// update array list of edit menu from clicked menu fragment
fun updateOrderEditList(menu: Menu){
    val editMenu = EditQuantity(menu,1,"")
    editList.add(0,editMenu)
    rec_edit_quantity.adapter.notifyDataSetChanged()
}

// read argumen as order object
private fun readBundle(bundle: Bundle?) {
    if (bundle != null) {
        order = bundle.getParcelable(getString(R.string.key_pass_order))
    }
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.fragment_bayar, container, false)

    // get order
    readBundle(arguments)

    // change name order in header of view
    view.order_name.text = order.order

    // initial recyclerview edit item
    view.rec_edit_quantity.layoutManager = LinearLayoutManager(activity)
    view.rec_edit_quantity.isNestedScrollingEnabled = false
    view.rec_edit_quantity.hasFixedSize()
    view.rec_edit_quantity.adapter = EditQuantityAdapter(editList){ editPosition: Int -> editItemClicked(editPosition) }
    // initial recyclerview edit item data
    dataEditAdapter = EditQuantityAdapter(editList){ editPosition: Int -> editItemClicked(editPosition) }
    view.rec_edit_quantity.adapter = dataEditAdapter

    // initial recyclerview progress item
    view.rec_progress_antar.layoutManager = LinearLayoutManager(activity)
    view.rec_progress_antar.isNestedScrollingEnabled = false
    view.rec_progress_antar.hasFixedSize()
    view.rec_progress_antar.adapter = ProgressAntarAdapter(progressList)
    // initial recyclerview progress item data
    dataProgressAdapter = ProgressAntarAdapter(progressList)
    view.rec_progress_antar.adapter = dataProgressAdapter

    // setup pesan button
    btn_pesan.setOnClickListener {
        sendOrder()
    }

    // get detail service from server
    getOrderDetailService()

    return view
}

// call to get order detail from web service
private fun getOrderDetailService() {
    //temp
    progressList = getOrderData()
    dataProgressAdapter.updateData(progressList)
}

// send order list to server
private fun sendOrder(){
    val apiService : Service = Client.getClient()!!.create(Service::class.java)
    apiService.sendOrder(editList).enqueue(object : Callback<List<ProgressAntar>> {

        override fun onResponse(call: Call<List<ProgressAntar>>?, response: Response<List<ProgressAntar>>?) {
            if (response != null && response.isSuccessful) {
                val list = response.body()

                if (list == null || list.isEmpty()) {
                    Toast.makeText(activity, "Tidak ada daftar pembayaran", Toast.LENGTH_LONG).show()
                } else{
                    // empty edit list
                    editList = ArrayList()
                    dataEditAdapter.updateData(editList)
                    // refresh progress list
                    progressList = ArrayList(list)
                    dataProgressAdapter.updateData(progressList)
                }

            } else{
                Toast.makeText(activity, "Tidak ada daftar pembayaran", Toast.LENGTH_LONG).show()
            }
        }

        override fun onFailure(call: Call<List<ProgressAntar>>?, t: Throwable?) {
            Log.i("onFailure", t.toString())
            Toast.makeText(context, "Gagal", Toast.LENGTH_LONG).show()
        }
    })
}

// delete menu item before send
private fun editItemClicked(menuItem : Int){
    editList.removeAt(menuItem)
    rec_edit_quantity.adapter.notifyDataSetChanged()
}

// temp function
private fun getOrderData(): ArrayList<ProgressAntar>{
    val list = ArrayList<ProgressAntar>()
    list.add(ProgressAntar("1","Bakso",15000, 4,0,false))
    list.add(ProgressAntar("2","Teh Panas",  15000, 3,0, false))
    list.add(ProgressAntar("3","Mie Aceh",  15000, 5,5, true))
    list.add(ProgressAntar("4","Teh Dingin",  15000, 3,3, true))

    return list
}

override fun onResume() {
    super.onResume()
    getOrderDetailService()
}

}

這是活動類

class FragmentActivity : AppCompatActivity(), FragmentKategori.OnItemSelectedListener,
    FragmentMenu.OnItemSelectedListener {

// current order information
private lateinit var order: Orders

// action for item clicked on category fragment
override fun onCategoryItemSelected(category: Category) {
    val fragment = supportFragmentManager.findFragmentById(R.id.placeholder2) as FragmentMenu
    fragment.updateMenuList(category)
}

// action for item clicked on menu fragment
override fun onMenuItemSelected(menu: Menu) {
    val fragment = supportFragmentManager.findFragmentById(R.id.placeholder3) as FragmentBayar
    fragment.updateOrderEditList(menu)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.layout_fragment)
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
    supportActionBar?.setDisplayHomeAsUpEnabled(true)

    // get bundle from previous activity
    val bundle = this.intent.extras

    // get order
    if(bundle.containsKey(getString(R.string.passOrder))){
        order = bundle.getParcelable(getString(R.string.passOrder))

    }
    else {
        Toast.makeText(this, "Something wrong", Toast.LENGTH_SHORT).show()
        finish()
    }

    val fragment1 = FragmentKategori()
    val fragment2 = FragmentMenu()
    val fragment3 = FragmentBayar.newInstance(order)

    supportFragmentManager.beginTransaction()
            .replace(R.id.placeholder1,fragment1)
            .replace(R.id.placeholder2,fragment2)
            .replace(R.id.placeholder3,fragment3)
            .commit()
}

override fun onCreateOptionsMenu(menu: android.view.Menu?): Boolean {
    menuInflater.inflate(R.menu.search,menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    val id = item?.itemId

    if (id == R.id.search){
        swipeView()
    }else if (id == android.R.id.home){
        finish()
    }
    return super.onOptionsItemSelected(item)
}

// change view to search
private fun swipeView(){
    // show search view
    if (rec_menu.visibility == View.VISIBLE){
        rec_menu.visibility = View.GONE
        lay_search.visibility = View.VISIBLE
    }
    // show menu view
    else{
        rec_menu.visibility = View.VISIBLE
        lay_search.visibility = View.GONE
    }
}

}

如您的跟蹤所述,問題出在:

fun newInstance(order: Orders): FragmentBayar {
    val fragment = FragmentBayar()

    val bundle = Bundle()
    /* here --> */bundle.putParcelable(fragment.getString(R.string.key_pass_order), order)
    fragment.arguments = bundle
    return fragment
}

當您調用fragment.getString(R.string.key_pass_order) ,您需要將該片段附加到活動上以獲得上下文。 在您剛剛初始化片段時,沒有與之關聯的上下文。

無論如何,將Extras捆綁在一起的通常做法是聲明常量以寫入/讀取其屬性。 一個簡短的解釋是因為您不需要公開它,並且它們可以是該類范圍的私有對象。

例:

companion object {
    private const val KEY_PASS_ORDER = "KEY_PASS_ORDER"

    fun newInstance(order: Orders): FragmentBayar {
        val fragment = FragmentBayar()

        val bundle = Bundle()
        bundle.putParcelable(KEY_PASS_ORDER, order)
        fragment.arguments = bundle
        return fragment
    }
}

private fun readBundle(bundle: Bundle?) {
    if (bundle != null) {
        order = bundle.getParcelable(KEY_PASS_ORDER)
    }
}
    //------------------pass data one fragment to another fragment ------------
    First fragment

    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;

    public class FragmentOne extends Fragment {

        SendMessage SM;

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View rootView = inflater.inflate(
                    R.layout.fragment_one, container, false);
            return rootView;


        }

        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);

            Button btnPassData = (Button) view.findViewById(R.id.btnPassData);
            final EditText inData = (EditText) view.findViewById(R.id.inMessage);
            btnPassData.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    SM.sendData(inData.getText().toString().trim());
                }
            });

        }

        interface SendMessage {
            void sendData(String message);
        }

        @Override
        public void onAttach(Context context) {
            super.onAttach(context);

            try {
                SM = (SendMessage) getActivity();
            } catch (ClassCastException e) {
                throw new ClassCastException("Error in retrieving data. Please try again");
            }
        }
    }

    //------------------second fragment----------------------------



    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;

    public class FragmentTwo extends Fragment {

        TextView txtData;

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View rootView = inflater.inflate(
                    R.layout.fragment_two, container, false);
            return rootView;
        }

        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);

            txtData = (TextView)view.findViewById(R.id.txtData);
        }

        protected void displayReceivedData(String message


)
        {
            txtData.setText("Data received: "+message);
        }
    }

我之前遇到過這個問題,並通過此鏈接從Android Developer網站解決了
建立一個接口很重要,這樣片段可以通過它們的活動相互通信

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM