ورود

View Full Version : نمایش داده در spinner



ali_72
سه شنبه 26 خرداد 1394, 12:39 عصر
سلام

من داده هایی دارم به این شکل

http://s6.uplod.ir/i/00621/tlrb4qqr0677_t.jpg (http://uplod.ir/tlrb4qqr0677/Untitled2.png.htm)

مثلا 4 آیتم دارم هر آیتم دارای حدود 15 ساب ایتم است و هر ساب آیتم 3 مقدار دارد
من باید 4 آیتم اول را در یک spinner لود کنم
با توجه به اینکه کاربر کدام آیتم را انتخاب کرده ساب آیتم ها در spinner دوم لود شود
و در نهایت با توجه به اینکه کدام ساب آیتم انتخاب شه مشخصات ساب آیتم در یک سری text view نمایش داده شود

من یه array-string شامل 4 ایتم ایجاد کردم و در spinner لود کردم
و برای ساب ایتم های هر آیتم array -string های جدا گذاشتم
و با توجه به اینکه کدام ایتم انتخاب شده array-string مربوط به اون آیتم رو در spinner دوم لود کردم (برنامه پر از شرط های ثابت شده و اصلا کدنویسی قشنگی نیست)

در مورد مشخصات ساب آیتم اصلا نمیدونم با این ساختار چطور باید جلو برم و در برنامه پیاده سازی کنم
در برنامه نویسی ویندوز اپلیکیشن از ساختار xml استفاده میکردم
تو اندروید باید چی کار کرد؟

شما چه پیشنهادی دارید؟

djtrex
سه شنبه 26 خرداد 1394, 15:47 عصر
می تونید از adapter ها استفاده کنید. عملا تعداد کلاس ها و متد ها رو بیشتر می کنید اما کد تمیز تری دارید.


این برای ۲ لول هست ولی میتونید به هر تعداد خواستید گسترش بدید:

یه کلاس برای item هاتون در نظر میگیرید:

Item.java


//Item.java
class Item {

public String name;


public List<Item> subItems = new ArrayList<Item>();
}


یه آداپتور (اگه spinner ها با فرقی ندارند) برای spinner ها در نظر میگیرید:


//ItemSpinnerAdapter.java


public class ItemSpinnerAdapter extends ArrayAdapter<Item> {


private List<Item> items;




public ItemSpinnerAdapter(Context context, int resource, List<Item> objects) {
super(context, resource, objects);


items = objects;
}


public View getCustomView(int position, View convertView,
ViewGroup parent) {


//todo inflate view


return layout;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}


@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}


@Override
public Item getItem(int position) {


return items.get(position);
}


@Override
public int getCount() {
return items.size();
}
}




توی اکتویتی تون می تونید یه متد برای listener ها در نظر بگیرید (همچنین میتونید listener هارو به صورت inner class بذارید)


private void setupListeners(){


levelOneItemSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {


Item levelOneItem = levelOneItemAdapter.getItem(position);
levelTwoItemAdapter.clear();
levelTwoItemAdapter.addAll(levelOneItem.subItems);



levelTwoItemAdapter.notifyDataSetChanged();


}


@Override
public void onNothingSelected(AdapterView<?> parent) {
//todo whatever you do!
}
});
}


یه متد هم نیاز دارید adapter رو درست کنید و مقدار دهی کنید:


//... set adapters
private void setupSpinners(){


List<Item> levelOneItems = getLevelOneItems();


//fill level one adapter:
levelOneItemAdapter = new ItemSpinnerAdapter(this, android.R.layout.simple_spinner_item, levelOneItems);
levelOneItemSpinner.setAdapter(levelOneItemAdapter );


//fill level two adapter:
levelTwoItemAdapter = new ItemSpinnerAdapter(this, android.R.layout.simple_spinner_item, levelOneItems.get(0).subItems);
levelTwoItemSpinner.setAdapter(levelTwoItemAdapter );
}



این کد کامل نیست و فقط یه پیشنهاده. باید متناسب با نیاز خودتون تغییر بدید اما امیدوارم باعث بشه به یه کد تمیز تری برسید:)

ممکنه برای این نیاز هم کتابخانه ای ساخته شده باشه میتونید سایت android-arsenal.com رو چک کنید.

ali_72
چهارشنبه 27 خرداد 1394, 07:03 صبح
ممنون
تو کدنویسی باید آیتم ها رو اضافه کنم؟ همه آیتم ها ثابت هستند

djtrex
چهارشنبه 27 خرداد 1394, 11:21 صبح
ممنون
تو کدنویسی باید آیتم ها رو اضافه کنم؟ همه آیتم ها ثابت هستند

می تونید آیتم ها رو بذارید توی یه فایل json بعد توی مثلا res/raw یا assets قرار بدید با این ساختار:


{
"items": [
{
"name" : "1",
"subItems" : [
{
"name" : "1-1"
"subItems" : []
},
{
"name" : "1-2"
"subItems" : [
{
"name" : "1-2-1"
"subItems" : []
}
]
}
]
},
{
"name" : "2"
"subItems" : []
}
]

}



کلاس آیتم هاتونم شبیه اینه:


//Item.java
public class Item {
public String name;

public List<Item> subItems = new ArrayList<Item>();


}



و یه کلاس هم برای کل آیتم ها نیاز دارید:


//ItemCollection.java
public class ItemCollection {

public List<Item> items;
}


حالا دیتاتونو میتونید به این صورت از res/raw لود کنید:


InputStream inputStream = getResources().openRawResource(R.raw.items);


BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));


بعد با Gson می تونید خیلی راحت json رو به کلاس های ساده java تبدیل کنید یا برعکس (json serializer/deserializer). در ضمن این کتابخانه مال گوگل هست ولی باید جداگانه نصب کنید:)

برای تبدیل json تون به کلاس ItemCollection:


Gson gson = new Gson();
ItemCollection itemCollection = gson.fromJson(reader, ItemCollection.class);




---
می تونستید ساختار json تون رو به صورت آرایه بنویسید دیگه نیازی به کلاس ItemCollection نبود ولی اون موقع باید ۱-۲ خط کد بیشتر می نوشتید موقع کار با gson.
یا اینکه آیتم های زیر مجموعه رو از نوع ItemCollection بذارید. دیگه دست خودتونه :)

اگه json تون به صورت string باشه به جای reader می تونید همون رشته json رو پاس بدید دیگه نیازی به inputstream و ... نیست.

--
در مورد gson:
https://github.com/google/gson
http://www.studytrails.com/java/json/java-google-json-parse-json-to-java.jsp