זהו המשך לפוסט הקודם בנושא. תוצג כאן דוגמא המתבססת על הדוגמא שהוצגה בפוסט הקודם, עם מספר שיפורים:
- ביטול קלט הנתונים מתוך מערך ב-java.
- קליטת הנתונים מתבצעת בשתי דרכים:
- בהתחלה, ב-onCreate, קריאת נתונים מתוך קובץ = raw data.
- בהמשך ניתן להוסיף רשומות אינטראקטיבית, תוך שימוש במסך מיוחד לקליטת הנתונים.
- תוספת onChildClick listener.
השיפורים שהוכנסו לא קשורים ישירות לנושא ה-ExapndableList, והן רק משלבות "שיכלולים" נוספים כמו אפשרויות נוספות לקליטת נתונים מקובץ (BufferedReader) והכנסת נתונים אינטראקטיבית לתוך ה-Lists.
נתחיל עם תצונות המסכים.
המסך הראשון: המסך שנוצר אחרי onCreate. זהה כמעט לזה שבפוסט הקודם. נוסף כפתור להוספת פריט לרשימה.
המסך השני, מסך להוספת פריט לרשימה:
המסך הנ"ל כולל הכנסת שדות לתוך EditView. שם העיר נבחר עם Spinner.
הנתונים ימשיכו להיות מסודרים בקבוצות לפי שם העיר.
נסתכל על הקבצים.
קובץ ה-layout של המסך הראשי דומה לזה שבפוסט הקודם. נווסף רק הכפתור. הנה תוכנו:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/add_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/button_add_entry"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:gravity="center"
android:textStyle="bold"
android:text="@string/address_book_title"
/>
<ExpandableListView android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/add_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/button_add_entry"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:gravity="center"
android:textStyle="bold"
android:text="@string/address_book_title"
/>
<ExpandableListView android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
קובץ ה-layout של האיבר ברשימת ה-child לא השתנה. אציג אותו שוב בכל זאת:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/textview_name"
android:paddingLeft="5px"
android:textSize="15px"
android:layout_width="120px"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/textview_address"
android:textSize="10px"
android:layout_width="120px"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/textview_tel"
android:textSize="10px"
android:layout_width="120px"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/textview_name"
android:paddingLeft="5px"
android:textSize="15px"
android:layout_width="120px"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/textview_address"
android:textSize="10px"
android:layout_width="120px"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/textview_tel"
android:textSize="10px"
android:layout_width="120px"
android:layout_height="wrap_content"/>
</LinearLayout>
הנה קובץ ה-layout של המסך השני - המסך להוספת פריט. שם הקובץ:activity2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/top_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/top_title"
/>
<TextView
android:id="@+id/textview_city_spinner_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/city_spinner_title"
/>
<Spinner android:id="@+id/city_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<TextView
android:id="@+id/textview_name_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/textview_name_title"
/>
<EditText
android:id="@+id/edit_text_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<TextView
android:id="@+id/textview_address_title"
android:padding="10dip"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/textview_address_title"
/>
<EditText
android:id="@+id/edit_text_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<TextView
android:id="@+id/textview_tel_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/textview_tel_title"
/>
<EditText
android:id="@+id/edit_text_tel_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<Button
android:id="@+id/button_commit"
android:text="@string/button_commit_entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
</Button>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/top_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/top_title"
/>
<TextView
android:id="@+id/textview_city_spinner_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/city_spinner_title"
/>
<Spinner android:id="@+id/city_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<TextView
android:id="@+id/textview_name_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/textview_name_title"
/>
<EditText
android:id="@+id/edit_text_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<TextView
android:id="@+id/textview_address_title"
android:padding="10dip"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/textview_address_title"
/>
<EditText
android:id="@+id/edit_text_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<TextView
android:id="@+id/textview_tel_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="@string/textview_tel_title"
/>
<EditText
android:id="@+id/edit_text_tel_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
/>
<Button
android:id="@+id/button_commit"
android:text="@string/button_commit_entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
</Button>
</LinearLayout>
ישנם עוד שני קבצים שאציג לפני שנעבור לג'אוות:
- הקובץ שמכיל את רשימת הכתובות הראשונית.
- רשימת הערים עבור ה-spinner.
הנה קובץ רשימת הכתובות הראשונית. שם קובץ: phonebook.txt והוא יושב ב/layout/raw.
Tel Aviv, David Levi, Nordau 8,052-2323232
Haifa, Yosi Das,Lilinblum 33,03-2323244
Tel Aviv, Rami Kook,Gordon 12,03-2323221
Tel Aviv, Sami Nof,Gordon 12,03-2323221
Haifa, David Levi, Nordau 8,052-2323232
Jerusalem,Yosi Das,Lilinblum 33,03-2323244
Tel Aviv,Dafi Cin,Gordon 12,03-2323221
Haifa, Iris Hadad, Has 8,052-2323432
Tel Aviv,Rafi Masmus,Jabotinski 313,03-2323244
Jerusalem,Jako Bilbo,Sokolov 32,02-2323221
Haifa, Itzik Solo,Sokolov 32,03-2324221
Tel Aviv,Nahum Fantog,King George 32,03-2324221
Tel Aviv,Irit Singer,King David 32,03-2388221
Haifa, Yosi Das,Lilinblum 33,03-2323244
Tel Aviv, Rami Kook,Gordon 12,03-2323221
Tel Aviv, Sami Nof,Gordon 12,03-2323221
Haifa, David Levi, Nordau 8,052-2323232
Jerusalem,Yosi Das,Lilinblum 33,03-2323244
Tel Aviv,Dafi Cin,Gordon 12,03-2323221
Haifa, Iris Hadad, Has 8,052-2323432
Tel Aviv,Rafi Masmus,Jabotinski 313,03-2323244
Jerusalem,Jako Bilbo,Sokolov 32,02-2323221
Haifa, Itzik Solo,Sokolov 32,03-2324221
Tel Aviv,Nahum Fantog,King George 32,03-2324221
Tel Aviv,Irit Singer,King David 32,03-2388221
כל רשומה נמצאת בשורה נפרדת, והשדות מופרדים עם ",".
רשימת הערים עבור ה-spinner. נמצא ב: values/arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="cities">
<item>Afula</item>
<item>Bat-Yam</item>
<item>CarCoor</item>
<item>Dimona</item>
<item>Eilta</item>
<item>Fasuta</item>
<item>Ganei Tikva</item>
<item>Haifa</item>
<item>Izrael</item>
<item>Jerusalem</item>
<item>Kiriat Shmona</item>
<item>Liman</item>
<item>Metula</item>
<item>Naharia</item>
<item>Ofakim</item>
<item>Petah=Tikva</item>
<item>Qualkilia</item>
<item>Ramat Gan</item>
<item>Shfayim</item>
<item>Tel Aviv</item>
</array>
</resources>
<resources>
<array name="cities">
<item>Afula</item>
<item>Bat-Yam</item>
<item>CarCoor</item>
<item>Dimona</item>
<item>Eilta</item>
<item>Fasuta</item>
<item>Ganei Tikva</item>
<item>Haifa</item>
<item>Izrael</item>
<item>Jerusalem</item>
<item>Kiriat Shmona</item>
<item>Liman</item>
<item>Metula</item>
<item>Naharia</item>
<item>Ofakim</item>
<item>Petah=Tikva</item>
<item>Qualkilia</item>
<item>Ramat Gan</item>
<item>Shfayim</item>
<item>Tel Aviv</item>
</array>
</resources>
הנה הגאוות. קודם כל הקובץ הראשי. לא ארחיב ואחזור על ההברים שניתנו בפוסט הקודם.
ה-class הראשי:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.ExpandableListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.Toast;
public class MyExapandablePart2 extends ExpandableListActivity {
private static final int CREATE_LIST_ENTRY = 1;
private static final String CITY = "CITY";
private static final String NAME = "NAME";
private static final String ADDRESS = "ADDRESS";
private static final String TEL = "TEL";
private ExpandableListAdapter adapter;
ArrayList<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
ArrayList<String> cityList = new ArrayList<String>();
ArrayList<List<Map<String, String>>> childrenData = new ArrayList<List<Map<String, String>>>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buildListsFromFile();
adapter = new SimpleExpandableListAdapter(
this,
groupData,
android.R.layout.simple_expandable_list_item_1,
new String[] { CITY },
new int[] { android.R.id.text1 },
childrenData,
R.layout.child_list_entry,
new String[] { NAME, ADDRESS, TEL },
new int[] { R.id.textview_name, R.id.textview_address, R.id.textview_tel }
);
setListAdapter(adapter);
Button buttonAddEntry = (Button)findViewById(R.id.add_entry);
buttonAddEntry.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MyExapandablePart2.this, EntryAddActivity.class);
startActivityForResult(intent,CREATE_LIST_ENTRY );
}
});
}
private void buildListsFromFile(){
InputStream inputStream = this.getResources().openRawResource(R.raw.phonebook);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
try{
String line = "";
while ((line = bufferedReader.readLine()) != null) {
String[] strings = line.split(",");
String city = strings[0].trim();
String name = strings[1].trim();
String address = strings[2].trim();
String tel = strings[3].trim();
buildListsEntry(city, name, address, tel);
Log.d("ronen post buildListsEntry",""+city);
}
}catch(Exception e){
// get class name:
Log.e(getClass().getSimpleName(), "readInputFile problem");
}
}
Map<String, String> groupMap = new HashMap<String, String>();
private void buildListsEntry(String city, String name, String address, String tel){
if(-1 == cityList.indexOf(city)){
groupMap = new HashMap<String, String>();
groupData.add(groupMap);
groupMap.put(CITY, city);
cityList.add(city);
ArrayList<Map<String, String>> child = new ArrayList<Map<String, String>>();
childrenData.add(child);
}
List<Map<String, String>> childCurr =childrenData.get(cityList.indexOf(city));
Map<String, String> childMap = new HashMap<String, String>();
childCurr.add(childMap);
childMap.put(NAME, name);
childMap.put(ADDRESS, address );
childMap.put(TEL, tel );
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CREATE_LIST_ENTRY) {
if (resultCode == RESULT_OK) {
String city = data.getStringExtra("city");
String name = data.getStringExtra("name");
String address = data.getStringExtra("address");
String tel = data.getStringExtra("tel");
buildListsEntry(city, name, address, tel);
}
}
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
Toast.makeText(this,"Selected item: groupPosition = "+groupPosition+"\nChild Positin = "+childPosition+"\nid= "+id,Toast.LENGTH_LONG).show();
return true;
}
}
Log.e(getClass().getSimpleName(), "readInputFile problem");
}
}
Map<String, String> groupMap = new HashMap<String, String>();
private void buildListsEntry(String city, String name, String address, String tel){
if(-1 == cityList.indexOf(city)){
groupMap = new HashMap<String, String>();
groupData.add(groupMap);
groupMap.put(CITY, city);
cityList.add(city);
ArrayList<Map<String, String>> child = new ArrayList<Map<String, String>>();
childrenData.add(child);
}
List<Map<String, String>> childCurr =childrenData.get(cityList.indexOf(city));
Map<String, String> childMap = new HashMap<String, String>();
childCurr.add(childMap);
childMap.put(NAME, name);
childMap.put(ADDRESS, address );
childMap.put(TEL, tel );
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CREATE_LIST_ENTRY) {
if (resultCode == RESULT_OK) {
String city = data.getStringExtra("city");
String name = data.getStringExtra("name");
String address = data.getStringExtra("address");
String tel = data.getStringExtra("tel");
buildListsEntry(city, name, address, tel);
}
}
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
Toast.makeText(this,"Selected item: groupPosition = "+groupPosition+"\nChild Positin = "+childPosition+"\nid= "+id,Toast.LENGTH_LONG).show();
return true;
}
}
ה-class (כמובן extends ExpandableListActivity) כולל את המתודות הבאות:
- onCreate
- buildListsFromFile
- buildListsEntry
- onActivityResult
- onChildClick
הנה ה-class השני, שמופעל ע"י intent ב-onClick callback של הכפתור.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
public class EntryAddActivity extends Activity {
EditText editTextName;
EditText editTextaddress;
EditText editTexttel;
Spinner spinnerCity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity2);
spinnerCity = (Spinner) findViewById(R.id.city_spinner);
editTextName = (EditText) findViewById(R.id.edit_text_name);
editTextaddress = (EditText)findViewById(R.id.edit_text_address);
editTexttel = (EditText)findViewById(R.id.edit_text_tel_number);
Button buttonCommit = (Button)findViewById(R.id.button_commit);
MyClickInterface buttonListener = new MyClickInterface();
buttonCommit.setOnClickListener(buttonListener);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getResources()
.getStringArray(R.array.cities));
spinnerCity.setAdapter(adapter);
}
public class MyClickInterface implements View.OnClickListener{
@Override
public void onClick(View v){
String myName = editTextName.getText().toString();
String myAddress = editTextaddress.getText().toString();
String myTel = editTexttel.getText().toString();
String myCity = spinnerCity.getSelectedItem().toString();
Intent intent = new Intent();
intent.putExtra("city", myCity);
intent.putExtra("name", myName );
intent.putExtra("address", myAddress);
intent.putExtra("tel", myTel);
setResult(RESULT_OK,intent);
finish();
}
}
}
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
public class EntryAddActivity extends Activity {
EditText editTextName;
EditText editTextaddress;
EditText editTexttel;
Spinner spinnerCity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity2);
spinnerCity = (Spinner) findViewById(R.id.city_spinner);
editTextName = (EditText) findViewById(R.id.edit_text_name);
editTextaddress = (EditText)findViewById(R.id.edit_text_address);
editTexttel = (EditText)findViewById(R.id.edit_text_tel_number);
Button buttonCommit = (Button)findViewById(R.id.button_commit);
MyClickInterface buttonListener = new MyClickInterface();
buttonCommit.setOnClickListener(buttonListener);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getResources()
.getStringArray(R.array.cities));
spinnerCity.setAdapter(adapter);
}
public class MyClickInterface implements View.OnClickListener{
@Override
public void onClick(View v){
String myName = editTextName.getText().toString();
String myAddress = editTextaddress.getText().toString();
String myTel = editTexttel.getText().toString();
String myCity = spinnerCity.getSelectedItem().toString();
Intent intent = new Intent();
intent.putExtra("city", myCity);
intent.putExtra("name", myName );
intent.putExtra("address", myAddress);
intent.putExtra("tel", myTel);
setResult(RESULT_OK,intent);
finish();
}
}
}
ב-onClick של כפתור ה-Commit מעבירים את הנתונים שהוכנסו דרך ה-EditViews וה-spinner לשדה ה-extra של ה-Intent, והם "משוגרים" חזרה ל-class השני, שם יטופלו ע"י המתודה onActivityResult - ה-callback שמטפל בהודעת ה-Intent החוזר.
הפעם לא ארחיב בהסברים מעבר לזה. אין כאן מרכיבים "חדשים".
תודה על הפרסום , אבל אתה יכול להוסיף גם את האלמנט של המיון לפי שמות ?
השבמחקאני משתמש באנדרואיד סטודיו , ושם אין את התיקייה raw איך אני בכל זאת יכול להעביר לו את המידע
השבמחק