casperhellas Δημοσ. 18 Φεβρουαρίου 2013 Δημοσ. 18 Φεβρουαρίου 2013 καλησπέρα παιδιά, έχω κάνει μια εφαρμογή όπου έχει Βάση Δεδομένων και θέλω όταν κάνει κλικ σε ένα listView (δηλ. κάποια από τις γραμμές) να λαμβάνω από την Βάση το κατάλληλο ΑΦΜ. Η διαδικασία που τραβάει από την Βάση τα δεδομένα είναι οκ, το πρόβλημα είναι όταν κάνει κλικ στην λίστα. Παραθέτω τον κώδικα καθώς και 2 εικόνες που δειχνουν πριν κάνω κλικ κ μετά που βγάζει σφάλμα ο κώδικας της onCreate είναι εδώ: lv = (ListView) findViewById(R.id.SelectOrChangeOwnerListView); ArrayList<String> mylv = new ArrayList<String>(); // Δημιουργία listadapter για τα στοιχεία listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow, mylv); //emfanise olous tous idioktites String sql = "SELECT name,surname,afm FROM owners ORDER BY surname ASC"; c = myDatabase.rawQuery(sql, null); // Ελέγχει αν επιστρέψει null το ερώτημα που εκτελέστηκε στην ΒΔ if ( c != null ) { if ( c.moveToFirst() ) { do { OwnerName = c.getString(c.getColumnIndex("name")); OwnerSurname = c.getString(c.getColumnIndex("surname")); OwnerAfm = c.getLong(c.getColumnIndex("afm")); listAdapter.add("Ον/μο: \t"+OwnerSurname +" "+OwnerName+"\n"+ "ΑΦΜ: \t\t"+OwnerAfm); } while (c.moveToNext()); } } c.moveToFirst(); lv.setAdapter( listAdapter ); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> lv, View view, int position, long id) { // Get the cursor, positioned to the corresponding row in the result set c = (Cursor) lv.getItemAtPosition(position); // Get the state's capital from this row in the database. int afmOwner = c.getInt(c.getColumnIndex("afm")); Toast.makeText(getApplicationContext(), afmOwner, Toast.LENGTH_SHORT).show(); } }); Το πρόβλημα που βγάζει είναι στην γραμμή: c = (Cursor) lv.getItemAtPosition(position);
Directx Δημοσ. 18 Φεβρουαρίου 2013 Δημοσ. 18 Φεβρουαρίου 2013 Ρίξε μια ματιά στο LogCat panel του Eclipse καθώς υπάρχουν καλές πιθανότητες να σου εξηγεί το πρόβλημα που οδηγεί σε crash.
casperhellas Δημοσ. 18 Φεβρουαρίου 2013 Μέλος Δημοσ. 18 Φεβρουαρίου 2013 LogCat: όπως έγραψα παραπάνω το πρόβλημα είναι στην γραμμή που υπάρχει ο Cursor (σειρά 71) 02-18 15:19:34.929: E/AndroidRuntime(5803): FATAL EXCEPTION: main 02-18 15:19:34.929: E/AndroidRuntime(5803): java.lang.ClassCastException: java.lang.String 02-18 15:19:34.929: E/AndroidRuntime(5803): at com.spiros.geofarmbeta.SelectOrChangeOwner$1.onItemClick(SelectOrChangeOwner.java:71) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.widget.AdapterView.performItemClick(AdapterView.java:284) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.widget.ListView.performItemClick(ListView.java:3749) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1993) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.os.Handler.handleCallback(Handler.java:587) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.os.Handler.dispatchMessage(Handler.java:92) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.os.Looper.loop(Looper.java:130) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.app.ActivityThread.main(ActivityThread.java:3687) 02-18 15:19:34.929: E/AndroidRuntime(5803): at java.lang.reflect.Method.invokeNative(Native Method) 02-18 15:19:34.929: E/AndroidRuntime(5803): at java.lang.reflect.Method.invoke(Method.java:507) 02-18 15:19:34.929: E/AndroidRuntime(5803): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 02-18 15:19:34.929: E/AndroidRuntime(5803): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 02-18 15:19:34.929: E/AndroidRuntime(5803): at dalvik.system.NativeStart.main(Native Method)
Directx Δημοσ. 18 Φεβρουαρίου 2013 Δημοσ. 18 Φεβρουαρίου 2013 LogCat: 02-18 15:19:34.929: E/AndroidRuntime(5803): FATAL EXCEPTION: main 02-18 15:19:34.929: E/AndroidRuntime(5803): java.lang.ClassCastException: java.lang.String 02-18 15:19:34.929: E/AndroidRuntime(5803): at com.spiros.geofarmbeta.SelectOrChangeOwner$1.onItemClick(SelectOrChangeOwner.java:71) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.widget.AdapterView.performItemClick(AdapterView.java:284) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.widget.ListView.performItemClick(ListView.java:3749) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1993) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.os.Handler.handleCallback(Handler.java:587) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.os.Handler.dispatchMessage(Handler.java:92) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.os.Looper.loop(Looper.java:130) 02-18 15:19:34.929: E/AndroidRuntime(5803): at android.app.ActivityThread.main(ActivityThread.java:3687) 02-18 15:19:34.929: E/AndroidRuntime(5803): at java.lang.reflect.Method.invokeNative(Native Method) 02-18 15:19:34.929: E/AndroidRuntime(5803): at java.lang.reflect.Method.invoke(Method.java:507) 02-18 15:19:34.929: E/AndroidRuntime(5803): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 02-18 15:19:34.929: E/AndroidRuntime(5803): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 02-18 15:19:34.929: E/AndroidRuntime(5803): at dalvik.system.NativeStart.main(Native Method) Το πρόβλημα έρχεται από την ανάθεση του Item στο "c" το οποίο είναι cursor αλλά το Item (πρέπει να) είναι String οπότε παρουσιάζεται εξαίρεση εσφαλμένου-cast (δεν μπορεί το String να γίνει Cursor).
casperhellas Δημοσ. 18 Φεβρουαρίου 2013 Μέλος Δημοσ. 18 Φεβρουαρίου 2013 Σύμφωνα με αυτό το παράδειγμα: http://www.mysamplecode.com/2012/07/android-listview-cursoradapter-sqlite.html?showComment=1361185847960#c9083045286417211666 βλέπω τα παρακάτω: ListView listView = (ListView) findViewById(R.id.listView1); // Assign adapter to ListView listView.setAdapter(dataAdapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> listView, View view, int position, long id) { // Get the cursor, positioned to the corresponding row in the result set Cursor cursor = (Cursor) listView.getItemAtPosition(position); // Get the state's capital from this row in the database. String countryCode = cursor.getString(cursor.getColumnIndexOrThrow("code")); Toast.makeText(getApplicationContext(), countryCode, Toast.LENGTH_SHORT).show(); } }); Δεν πρέπει να υπάρχει πρόβλημα. Πως θα μπορέσω να το διορθώσω? υπάρχει κάποιο άλλο παράδειγμα? Ευχαριστώ πολύ για την βοήθεια σου...
Directx Δημοσ. 18 Φεβρουαρίου 2013 Δημοσ. 18 Φεβρουαρίου 2013 Σύμφωνα με αυτό το παράδειγμα: http://www.mysamplecode.com/2012/07/android-listview-cursoradapter-sqlite.html?showComment=1361185847960#c9083045286417211666 βλέπω τα παρακάτω: ListView listView = (ListView) findViewById(R.id.listView1); // Assign adapter to ListView listView.setAdapter(dataAdapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> listView, View view, int position, long id) { // Get the cursor, positioned to the corresponding row in the result set Cursor cursor = (Cursor) listView.getItemAtPosition(position); // Get the state's capital from this row in the database. String countryCode = cursor.getString(cursor.getColumnIndexOrThrow("code")); Toast.makeText(getApplicationContext(), countryCode, Toast.LENGTH_SHORT).show(); } }); Δεν πρέπει να υπάρχει πρόβλημα. Πως θα μπορέσω να το διορθώσω? υπάρχει κάποιο άλλο παράδειγμα? Ευχαριστώ πολύ για την βοήθεια σου... Στο παράδειγμα, το Adapter προφανώς επιστρέφει έναν Cursor, στο δικό σου πιθανόν επιστρέφει ένα String οπότε εκεί είναι το θέμα σου, μια λύση είναι να γράψεις ένα δικό σου Adapter που να επιστρέφει το επιθυμητό (Cursor) ή ακόμα καλύτερα ένα String με κάποιο ID μοναδικό για κάθε εγγραφή και να κάνεις έτσι την δουλειά σου (δίχως να κρατάς και ένα σωρό Cursor ανοιχτά).
casperhellas Δημοσ. 18 Φεβρουαρίου 2013 Μέλος Δημοσ. 18 Φεβρουαρίου 2013 αφού το κάνω casting σε cursor.... Τέσπα, σε ευχαριστώ για την βοήθεια και τις απαντήσεις σου! Νασαι καλά! Αν έχεις κάποιο παράδειγμα θα με βοηθούσε αρκετά. ---------------------------- Βασικά ούτε σε αυτόν επιστρέφει Cursor γιατί και αυτός το κάνει casting. Το είδα και επιστρέφει AdapterView
Directx Δημοσ. 18 Φεβρουαρίου 2013 Δημοσ. 18 Φεβρουαρίου 2013 (επεξεργασμένο) αφού το κάνω casting σε cursor.... Τέσπα, σε ευχαριστώ για την βοήθεια και τις απαντήσεις σου! Νασαι καλά! Αν έχεις κάποιο παράδειγμα θα με βοηθούσε αρκετά. ---------------------------- Βασικά ούτε σε αυτόν επιστρέφει Cursor γιατί και αυτός το κάνει casting. Το είδα και επιστρέφει AdapterView Αυτός όμως χρησιμοποιεί το SimpleCursorAdapter ενώ εσύ το ArrayAdapter συνεπώς υπάρχει μεγάλη διαφορά μεταξύ του τι κάνει εκείνος και τι εσύ, το SimpleCursorAdapter μπορεί να γίνει cast σε Cursor αν είναι πακεταρισμένο σε κάποιο άλλο πιο γενικό class αλλά το ArrayAdapter προφανώς όχι διότι είναι <String>. --UPDATE: Αναρτώ μια πολύ απλή (και γρήγορα γραμμένη) υλοποίηση ενός γενικού Adapter (βασισμένο στο BaseAdapter) το οποίο επιστρέφει ένα Pair<String, String> ενώ δοκιμάζει να εφαρμώσει και cache κατά το "getView" (επ' αυτού ίσως να μου έχει ξεφύγει κάτι καθώς για ένα διάστημα δεν έγραφα πολύ σε Android και κάποια πράγματα έχουν ατονήσει). Σίγουρα η Google προσφέρει πολλά και ενδιαφέροντα έτοιμα Adapter αλλά όταν θες να κάνεις κάτι πολύ ιδιαίτερο (οπτικά ή λειτουργικά) το BaseAdapter είναι ενδεχομένως η καλύτερη λύση. Για την ιστορία λοιπόν.. public class StringlistActivity extends Activity { ListView myListView; Vector<Pair<String, String>> Data; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Arbitrary data for 10 users Data = new Vector<Pair<String, String>>(); for(int User = 0; User < 1000; User++) Data.add(Pair.create("USER " + String.valueOf(User), String.valueOf(101 + User))); // Setup ListView & ListView adapter myListView = (ListView)findViewById(R.id.listView1); myListView.setAdapter(new BaseAdapter() { @Override public View getView(int position, View convertView, ViewGroup parent) { View myItemView; final TextView UserName, UserAFM; // Cache View (save time by calling only once .infalte & .findViewById) if(convertView == null) { myItemView = View.inflate(getApplicationContext(), R.layout.myitem, null); UserName = (TextView)myItemView.findViewById(R.id.textViewName); UserAFM = (TextView)myItemView.findViewById(R.id.textViewAFM); myItemView.setTag(Pair.create(UserName, UserAFM)); } else { myItemView = convertView; final Pair<TextView, TextView> Cache = (Pair<TextView, TextView>)convertView.getTag(); UserName = Cache.first; UserAFM = Cache.second; } UserName.setText(Data.get(position).first); UserAFM.setText(Data.get(position).second); return myItemView; } @Override public long getItemId(int position) { return position; } @Override public Object getItem(int arg0) { return Data.get(arg0); } @Override public int getCount() { return Data.size(); } }); // User clicked on ListView myListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { final Pair<String, String> User = Data.get(position); // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), String.format("User Name = \"%s\"\nUser AFM = \"%s\"", User.first, User.second), Toast.LENGTH_LONG).show(); } }); } } * Θεωρώ ότι ο χρήστης παρέχει ένα View για τα Item του ListView ονόματι "myitem" με τουλάχιστον δυο TextView (textViewName, textViewAFM) στα οποία γράφουμε την ονομασία ενός ατόμου (UserName) και το ΑΦΜ (UserAFM) του.** Προς χάρην απλότητας όλα τα δεδομένα του ο BaseAdapter τα λαμβάνει από το Vector<Pair<String, String>> Data. *** Έχει δοκιμαστεί σε Android 2.2 emulator. Video παρουσίασης: http://www.youtube.com/watch?v=vVN_A2A9-4M Επεξ/σία 18 Φεβρουαρίου 2013 από Directx
casperhellas Δημοσ. 18 Φεβρουαρίου 2013 Μέλος Δημοσ. 18 Φεβρουαρίου 2013 Καλώς θα το ψάξω να δω πως θα γίνει διαφορετικά. Ευχαριστώ!
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα