在将数据从片段传递到另一个片段时遇到问题。
错误:
原因: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.Activity.performCreate(Activity.java:6303) 在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 在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
}
}
}
答案 0 :(得分:0)
如您的踪迹所述,问题出在:
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)
}
}
答案 1 :(得分:0)
//------------------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);
}
}
答案 2 :(得分:0)
我之前曾遇到过这个问题,并从link的Android Developer网站解决了这个问题
建立一个接口很重要,这样片段可以通过它们的活动相互通信