Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

καλησπέρα παιδιά,

έχω κάνει μια εφαρμογή όπου έχει Βάση Δεδομένων και θέλω όταν κάνει κλικ σε ένα 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);

post-173291-0-73506800-1361191932_thumb.png

post-173291-0-66309400-1361191938_thumb.png

Δημοσ.

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)

Δημοσ.

 

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).

Δημοσ.

Σύμφωνα με αυτό το παράδειγμα:

 

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();
 
   }
  });

Δεν πρέπει να υπάρχει πρόβλημα.

 

Πως θα μπορέσω να το διορθώσω? υπάρχει κάποιο άλλο παράδειγμα?

 

Ευχαριστώ πολύ για την βοήθεια σου...

Δημοσ.

Σύμφωνα με αυτό το παράδειγμα:

 

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 ανοιχτά).

Δημοσ.

αφού το κάνω casting σε cursor.... :unsure:

 

Τέσπα, σε ευχαριστώ για την βοήθεια και τις απαντήσεις σου! Νασαι καλά!

 

Αν έχεις κάποιο παράδειγμα θα με βοηθούσε αρκετά.

 

----------------------------

 

 

Βασικά ούτε σε αυτόν επιστρέφει Cursor γιατί και αυτός το κάνει casting. Το είδα και επιστρέφει AdapterView

Δημοσ. (επεξεργασμένο)

αφού το κάνω casting σε cursor.... :unsure:

 

Τέσπα, σε ευχαριστώ για την βοήθεια και τις απαντήσεις σου! Νασαι καλά!

 

Αν έχεις κάποιο παράδειγμα θα με βοηθούσε αρκετά.

 

----------------------------

 

 

Βασικά ούτε σε αυτόν επιστρέφει 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

 

 

 

Επεξ/σία από Directx

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...