Java 使用包将 ArrayList 从片段传递到另一个片段(扩展 ListFragment),seListAdapter 运行时错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23103028/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pass ArrayList from fragment to another fragment(extends ListFragment) using bundle, seListAdapter runtime error
提问by t_godd
I have tried using Static variable for the ArrayList but in the ListFragment class, while debugging it's value is null.
我曾尝试对 ArrayList 使用静态变量,但在 ListFragment 类中,调试时它的值为空。
I think the ListFragment gets created before initialising the ArrayList, thats why it's null, but not sure.
我认为 ListFragment 是在初始化 ArrayList 之前创建的,这就是它为空的原因,但不确定。
Suggest if i can use any other way to send the inflated ArrayList from Fragment class to other Fragment class which extends ListFragment.
建议我是否可以使用任何其他方式将膨胀的 ArrayList 从 Fragment 类发送到扩展 ListFragment 的其他 Fragment 类。
Thanks in advance.
提前致谢。
Objective (This is the clue, what needs to be done)
目标(这是线索,需要做什么)
In the Monday_fragment's onStart() method use the findByView() method to find the label for the save entry button in the pages view. Using the reference to the button attach a setOnClickListener() method to the save button. You will need to save the time and the diary entry strings contained in the EditText fields on the page in this method.
在 Monday_fragment 的 onStart() 方法中,使用 findByView() 方法在页面视图中查找保存条目按钮的标签。使用对按钮的引用将 setOnClickListener() 方法附加到保存按钮。您将需要在此方法中保存页面上 EditText 字段中包含的时间和日记条目字符串。
Use findViewById() to also get a reference to the first EditText field and use this to get the text of the field as a string and save it to a string. Repeat this for the next EditText - the diary entry. You will need a publicly accessible variable to store a reference for the day (Monday..Friday), the date time string, and the diary entry string. Create a new class (diaryLogs) with these fields to hold the values and a single constructor that takes an int (0 Mon, 1 Tue, 2 Wed etc) and two strings for the date time and diary entry to initialise an instance of the object. As a number of entries will be made for the same day, use an ArrayList < diaryLogs > to store the values. As this value will be shared between fragments declare the variable as static in the MainActivity class. Use the .add() method of ArrayList to add the new diaryLog to the ArrayList in your setOnClickListener() method. Repeat this operation for the other diary page fragments.
使用 findViewById() 还可以获取对第一个 EditText 字段的引用,并使用它来获取该字段的文本作为字符串并将其保存为字符串。对下一个 EditText - 日记条目重复此操作。您将需要一个可公开访问的变量来存储当天(星期一..星期五)、日期时间字符串和日记条目字符串的引用。使用这些字段创建一个新类 (diaryLogs) 来保存值和一个构造函数,该构造函数采用 int(0 Mon、1 Tue、2 Wed 等)和两个字符串作为日期时间和日记条目以初始化对象的实例. 由于将在同一天创建多个条目,因此请使用 ArrayList < diaryLogs > 来存储这些值。由于此值将在片段之间共享,因此在 MainActivity 类中将变量声明为静态。使用 。ArrayList 的 add() 方法将新的 diaryLog 添加到 setOnClickListener() 方法中的 ArrayList。对其他日记页面片段重复此操作。
The monday_list fragment consists of a ListView and a button used to return to the Monday_fragment page. Create these objects in the monday_list xml file. Create a Monday_list_fragment that extends the ListFragment class. In the onCreateView() method inflate() the monday_list resource.
monday_list 片段由一个 ListView 和一个用于返回到 Monday_fragment 页面的按钮组成。在 monday_list xml 文件中创建这些对象。创建一个扩展 ListFragment 类的 Monday_list_fragment。在 onCreateView() 方法 inflate() monday_list 资源。
In the onCreate() method you need to provide a single array of strings as the source for the list in the setListAdapter() method used to fill the ListView on the page. The strings are in your static ListArray variable in MainActivity. However, they are not in the form required and you must unpack the diaryLog elements to get to the required strings. To do this you must create a String array big enough to hold the strings to display. As this consistes of a date/time string followed by a diary entry string there will be two such strings for each diaryLog element. Use a Iterator to iterate through your ListArray. Copy the date string and diary string strings into your local string. Then use this local string as the relevant parameter of setListAdapter() so that the ListView displays the required strings.
在 onCreate() 方法中,您需要提供一个字符串数组作为 setListAdapter() 方法中用于填充页面上的 ListView 的列表的源。字符串位于 MainActivity 中的静态 ListArray 变量中。但是,它们不是所需的形式,您必须解压缩 diaryLog 元素才能获得所需的字符串。为此,您必须创建一个足够大的 String 数组以容纳要显示的字符串。由于它由一个日期/时间字符串后跟一个日记条目字符串组成,因此每个 diaryLog 元素将有两个这样的字符串。使用 Iterator 迭代您的 ListArray。将日期字符串和日记字符串字符串复制到您的本地字符串中。然后使用这个本地字符串作为setListAdapter()的相关参数,让ListView显示需要的字符串。
Add the click handler in the MainActivity java file so that a click on the Save Diary Entries button in the Monday fragment page causes the Monday_list_fragment to be made visible using the FragmentManager. Also add a click handler in MainActivity so that a click on the Return to Monday Diary button returns to the Monday_fragment page.
在 MainActivity java 文件中添加单击处理程序,以便单击 Monday 片段页面中的 Save Diary Entries 按钮会导致使用 FragmentManager 使 Monday_list_fragment 可见。还要在 MainActivity 中添加一个单击处理程序,以便单击 Return to Monday Diary 按钮返回到 Monday_fragment 页面。
UPDATEClass MainActivity
更新类 MainActivity
public class MainActivity extends Activity {
public static int Monday=0;
/*public static int Tuesday=1;
public static int Wednesday=2;
public static int Thursday=3;
public static int Friday=4;
public static String timeEntry;
public static String entryEntered;*/
// public static ArrayList<String> logs;
//public static String[] entry;
//public static String time;
//public static String text;
//public static String totalEntry;
//public static ArrayList<DiaryLogs> diaryLogs;
//public static ArrayList<DiaryLogs> test;
//public static DiaryLogs[] entryLogs;
//public static ArrayAdapter<DiaryLogs> monAdapter;
//public static ArrayList< String > myStringList;
//public static ArrayList<DiaryLogs> entryLogs;
public static ArrayList<String> myStringList;
public static ArrayList<String> getMyStringList() {
return myStringList;
}
public void setMyStringList(ArrayList<String> myStringList) {
this.myStringList = myStringList;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Home_fragment hf = new Home_fragment();
fragmentTransaction.replace(android.R.id.content, hf);
fragmentTransaction.commit();
setContentView(R.layout.activity_main);
}
public void monClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Monday_fragment mf = new Monday_fragment();
fragmentTransaction.replace(android.R.id.content, mf);
fragmentTransaction.commit();
}
public void tuesClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Tuesday_fragment tf = new Tuesday_fragment();
fragmentTransaction.replace(android.R.id.content, tf);
fragmentTransaction.commit();
}
public void wedClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Wednesday_fragment wf = new Wednesday_fragment();
fragmentTransaction.replace(android.R.id.content, wf);
fragmentTransaction.commit();
}
public void thursClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Thursday_fragment thf = new Thursday_fragment();
fragmentTransaction.replace(android.R.id.content, thf);
fragmentTransaction.commit();
}
public void friClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Friday_fragment ff = new Friday_fragment();
fragmentTransaction.replace(android.R.id.content, ff);
fragmentTransaction.commit();
}
public void next_Home_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Monday_fragment mf = new Monday_fragment();
fragmentTransaction.replace(android.R.id.content, mf);
fragmentTransaction.commit();
}
public void previous_Home_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Friday_fragment ff = new Friday_fragment();
fragmentTransaction.replace(android.R.id.content, ff);
fragmentTransaction.commit();
}
public void next_Mon_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Tuesday_fragment tf = new Tuesday_fragment();
fragmentTransaction.replace(android.R.id.content, tf);
fragmentTransaction.commit();
}
public void previous_Mon_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Friday_fragment ff = new Friday_fragment();
fragmentTransaction.replace(android.R.id.content, ff);
fragmentTransaction.commit();
}
public void next_Tues_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Wednesday_fragment wf = new Wednesday_fragment();
fragmentTransaction.replace(android.R.id.content, wf);
fragmentTransaction.commit();
}
public void previous_Tues_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Monday_fragment mf = new Monday_fragment();
fragmentTransaction.replace(android.R.id.content, mf);
fragmentTransaction.commit();
}
public void next_Wed_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Thursday_fragment thf = new Thursday_fragment();
fragmentTransaction.replace(android.R.id.content, thf);
fragmentTransaction.commit();
}
public void previous_Wed_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Tuesday_fragment tf = new Tuesday_fragment();
fragmentTransaction.replace(android.R.id.content, tf);
fragmentTransaction.commit();
}
public void next_Thurs_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Friday_fragment ff = new Friday_fragment();
fragmentTransaction.replace(android.R.id.content, ff);
fragmentTransaction.commit();
}
public void previous_Thurs_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Wednesday_fragment wf = new Wednesday_fragment();
fragmentTransaction.replace(android.R.id.content, wf);
fragmentTransaction.commit();
}
public void next_Fri_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Monday_fragment ff = new Monday_fragment();
fragmentTransaction.replace(android.R.id.content, ff);
fragmentTransaction.commit();
}
public void previous_Fri_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Thursday_fragment wf = new Thursday_fragment();
fragmentTransaction.replace(android.R.id.content, wf);
fragmentTransaction.commit();
}
public void home_Click(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Home_fragment hf = new Home_fragment();
fragmentTransaction.replace(android.R.id.content, hf);
fragmentTransaction.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_profile:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Profile_fragment pf = new Profile_fragment();
fragmentTransaction.replace(android.R.id.content, pf);
fragmentTransaction.commit();
break;
case R.id.action_saveEntries:
break;
case R.id.action_sendAllEntries:
//call delete dialog
deleteDialog();
break;
}
return false;
}
@Override
public void onBackPressed() {
new AlertDialog.Builder(this).setIcon(R.drawable.ic_launcher)
.setTitle("Save entries to DB first?")
.setNegativeButton("No", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
// if no, close app
MainActivity.this.finish();
}
})
.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
// if ok, save entries to Database
}
})
.create().show();
}
public void deleteDialog() {
new AlertDialog.Builder(this).setIcon(R.drawable.ic_launcher)
.setTitle("Are you sure? This will delete all entries.")
.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.create().show();
}
}
Custom Object Class DiaryLogs
自定义对象类日记日志
public class DiaryLogs {
//public static ArrayList<DiaryLogs> entryLogs;
String timeEntry, entryEntered;
int day;
// single constructor that takes an integer and two string
public DiaryLogs(int day, String timeEntry, String entryEntered) {
super();
this.day = day;
this.timeEntry = timeEntry;
this.entryEntered = entryEntered;
}
public String getTimeEntry() {
return timeEntry;
}
public void setTimeEntry(String timeEntry) {
this.timeEntry = timeEntry;
}
public String getEntryEntered() {
return entryEntered;
}
public void setEntryEntered(String entryEntered) {
this.entryEntered = entryEntered;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.timeEntry + "\n" + this.entryEntered;
}
}
UPDATEClass Monday_fragment
更新类 Monday_fragment
public class Monday_fragment extends Fragment {
//public ArrayList<String> myStringList;
Bundle bundle;
ArrayList<DiaryLogs> entryLogs;
EditText timeText;
EditText entryText;
DiaryLogs dl;
String timeEntry;
String entryEntered;
ArrayList<String> myStringList;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.monday_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
currentDateTime();
super.onViewCreated(view, savedInstanceState);
}
public void currentDateTime() {
EditText timeText = (EditText) getView().findViewById(
R.id.dateTimeEText);
SimpleDateFormat df = new SimpleDateFormat("d/M/yyyy:H:m");
String dateTime = df.format(Calendar.getInstance().getTime());
timeText.setText(dateTime);
}
/*public ArrayList<String> toStringList(Collection<DiaryLogs> entryLogs) {
ArrayList<String> stringList = new ArrayList<String>();
for (DiaryLogs myobj : entryLogs) {
stringList.add(myobj.toString());
}
return stringList;
}*/
public ArrayList<String> toStringList(Collection<DiaryLogs> entryLogs) {
ArrayList<String> stringList = MainActivity.getMyStringList();
for (DiaryLogs myobj : entryLogs) {
String objctString = myobj.toString();
stringList.add(objctString);
}
((MainActivity)getActivity()).setMyStringList(stringList);
return stringList;
}
@Override
public void onStart() {
entryLogs = new ArrayList<DiaryLogs>();
timeText = (EditText) getView().findViewById(R.id.dateTimeEText);
entryText = (EditText) getView().findViewById(R.id.diaryEntryEText);
Button saveBtn = (Button) getView()
.findViewById(R.id.saveDiaryEntryBtn);
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
timeEntry = timeText.getText().toString();
entryEntered = entryText.getText().toString();
dl = new DiaryLogs(1, timeEntry, entryEntered);
entryLogs.add(dl);
//convert entryLogs to string array list
//myStringList = toStringList(entryLogs);
myStringList= MainActivity.getMyStringList();
myStringList = toStringList(entryLogs);
//myStringList.addAll(toStringList(entryLogs));
Toast.makeText(getActivity(), "Entry added \n" + dl,
Toast.LENGTH_SHORT).show();
entryText.setText("");
}
}
);
System.out.println(entryLogs);
Button showBtn = (Button) getView().findViewById(
R.id.showDiaryEntriesBtn);
showBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (myStringList != null) {
bundle = new Bundle();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Monday_list_fragment mlf = new Monday_list_fragment();
bundle.putStringArrayList("list", myStringList);
mlf.setArguments(bundle);
fragmentTransaction.replace(android.R.id.content, mlf);
fragmentTransaction.commit();
}
if (myStringList == null) {
Toast.makeText(getActivity(),
"No entry have been added yet", Toast.LENGTH_SHORT)
.show();
}
}
});
super.onStart();
}
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
}
Class Monday_list_fragment
类 Monday_list_fragment
public class Monday_list_fragment extends ListFragment {
ArrayList<String> test;
Bundle bundle;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bundle = getArguments();
System.out.println(bundle);
//test = bundle.getStringArrayList("list");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater
.inflate(R.layout.monday_list_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/* ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, test);
// once adapter set throws runtime error
setListAdapter(adapter);*/
}
}
回答by maddy d
You can only pass custom object or ArrayList of custom object via Bundle(or Intent)
when the object is either Parcelable
or Serializable
. One more thing if your fragments are in same activity then why you are passing array. you just create getter
and setter
for list in your Activity
and access them like ((Activity)getActivity).getArraylist()
in your listFragment. For creating object Parcelable
do something like below.
Bundle(or Intent)
当对象为Parcelable
或时,您只能通过自定义对象或自定义对象的 ArrayList 传递Serializable
。还有一件事,如果您的片段处于相同的活动中,那么您为什么要传递数组。您只需在您的列表中创建getter
和setter
获取列表,Activity
并像((Activity)getActivity).getArraylist()
在您的 listFragment 中一样访问它们。要创建对象,Parcelable
请执行以下操作。
import android.os.Parcel;
import android.os.Parcelable;
public class Address implements Parcelable {
private String name, address, city, state, phone, zip;
@Override
public int describeContents() {
return 0;
}
/*
THE ORDER YOU READ OBJECT FROM AND WRITE OBJECTS TO YOUR PARCEL MUST BE THE SAME
*/
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeString(address);
parcel.writeString(city);
parcel.writeString(state);
parcel.writeString(phone);
parcel.writeString(zip);
}
public Address(Parcel p){
name = p.readString();
address = p.readString();
city = p.readString();
state = p.readString();
phone = p.readString();
zip = p.readString();
}
// THIS IS ALSO NECESSARY
public static final Creator<Address> CREATOR = new Creator<Address>() {
@Override
public Address createFromParcel(Parcel parcel) {
return new Address(parcel);
}
@Override
public Address[] newArray(int i) {
return new Address[0];
}
};
}
回答by maddy d
I have seen your code for your given link and thats why I am posting a new Ans. One thing if you read your code carefully, you have declared ArrayAdapter<String>
in Monday_fragment
, so this list initialize every time when you replace this fragment with other. So just create a ArrayAdapter<String>
in MainActivity
and getter, setter
for the same and change your methode ArrayList<String> toStringList(Collection<DiaryLogs> entryLogs)
in the Monday_fragment
like below
我已经看到了您给定链接的代码,这就是我发布新 Ans 的原因。如果您仔细阅读代码,有一件事是在 中声明 ArrayAdapter<String>
的Monday_fragment
,因此每次将此片段替换为其他片段时都会初始化此列表。所以只需创建一个ArrayAdapter<String>
in MainActivity
and getter, setter
for the same 并ArrayList<String> toStringList(Collection<DiaryLogs> entryLogs)
在Monday_fragment
下面更改您的方法
public ArrayList<String> toStringList(Collection<DiaryLogs> entryLogs) {
ArrayList<String> stringList = ((MainActivity)getActivity()).getMyStringList();
for (DiaryLogs myobj : entryLogs) {
String objctString = myobj.toString();
stringList.add(objctString);
}
((MainActivity)getActivity()).setMyStringList(stringList);
return stringList;
}