5

私が試したこと


こんにちはみんな、私は最初に3つの列、RowID、imageID、テキストで埋めたデータベースを作成しました。その後、GridViewを作成しました。これは、データベースに入力された場合に使用されます。これで、onItemClickListnerを作成しました。このリストで、位置のimageIDを取得します。その後、このimageIDの後にDBテーブルを検索して、テキストを取得します。これは、他のテーブルに保存する必要があります。問題は、私がimageIDを取得していないことだと思います。また、DBのnothinのこの検索のように、Logcatを見ると、nullであることがわかります。したがって、おそらくimageIDまたはIを取得できませんでした。私のDBAdapterで検索してください。

質問


重要: ついにビューthxのIDをFuzzialLogicに取得しましたが、それでも問題があり、カーソル上に行を取得できません。ぜひご覧ください!


作品

ユーザーがクリックした画像のIDを取得できるように、コードで何を変更する必要がありますか。その後、そのImage-IDを使用してDBを検索し、Imageとともに保存したテキストを取得します。このようなものは後で私の他のテーブルに入れられます。

ここに、CodeとLogCat-Logが表示されます。誰かが必要な場合は、DatabaseAdapterも追加しました。事前にあなたの助けをありがとう!

コード


SFilterConfigActivity.class:

    package de.retowaelchli.filterit;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.Toast;
import android.*;

import de.retowaelchli.filterit.database.SmileyDBAdapter;
import de.retowaelchli.filterit.database.SFilterDBAdapter;
import de.retowaelchli.filterit.stats.ImageAdapter;




public class SFilterConfigActivity extends Activity {
    
    //Variablen deklarieren
    private String name;
    private String keyword;
    private String smiley;
    private String text;
    
    private String source;
    private Integer[] info;
    
    private SmileyDBAdapter SmileyHelper;
    private SFilterDBAdapter mDbHelper;
    
    
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sfilter_config);
    
      SmileyHelper = new SmileyDBAdapter(this);
      mDbHelper = new SFilterDBAdapter(this);
      
      getImages();
      grid();
    }


public void grid(){
    
    //Hier wird die GridView definiert und anschliesend über den ImageAdapter gefüllt
    final GridView gridview = (GridView) findViewById(R.id.SmileyGrind);
    gridview.setAdapter(new ImageAdapter(this, info));

    
    //Hier wird definiert was passiert wenn auf ein Bild in der GridView geklickt wird
    gridview.setOnItemClickListener(new OnItemClickListener(){
        
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            Toast.makeText(SFilterConfigActivity.this, "" + position, Toast.LENGTH_SHORT).show();
           // gridview.setSelection(position);
           // Funktioniert noch nich Custom GridView Layout dafür erstellen siehe Stackoverflow
            if(position == gridview.getSelectedItemPosition()){
                v.setBackgroundColor(0xFF00FF00);
                
            }
            else{
                v.setBackgroundColor(0x0000000);
            }
            
            //Hier wird herrausgefunden welche ID das Bild hat und in den jeweiligen String gespeichert
            source = (new Long(id)).toString();
            
            SmileyHelper.open();
            Cursor c = SmileyHelper.getSmiley(source);
            startManagingCursor(c);

            if (c.moveToFirst()) { 
                do { 
                text = c.getString(c.getColumnIndex(SmileyDBAdapter.SOURCE)); 
                smiley = c.getString(c.getColumnIndex(SmileyDBAdapter.INFO)); 
                
                } while (c.moveToNext());
            SmileyHelper.close();
            

            }

        }
        
    });
}


public Integer[] getImages(){
    
    SmileyHelper.open();
    
    Cursor c = SmileyHelper.getAllSmileys();
    
    ArrayList<Integer> infoList = new ArrayList<Integer>();
    
    c.getColumnIndex(SmileyDBAdapter.INFO);
    int ColumnIndex = c.getColumnIndex(SmileyDBAdapter.INFO);
    
    if(c!=null)
    {
       
       while(c.moveToNext()){
           String infoItem = c.getString( ColumnIndex );
           infoList.add(Integer.parseInt(infoItem));
       }
    }


    info = infoList.toArray(new Integer[]{});

    c.close();
    
    
    SmileyHelper.close();
  
    
    return info;
    
}



public void onClickSConfigSave(View v){
    
    EditText edtTextName = (EditText)findViewById(R.id.SFConfigName);
    EditText edtTextKeyword = (EditText)findViewById(R.id.SFConfigKeyword);
    
    name = edtTextName.getText().toString();
    keyword = edtTextKeyword.getText().toString();
    
    mDbHelper.open();
    mDbHelper.createSFilter(name, keyword, smiley, text);
    mDbHelper.close();
    
    final Intent i = new Intent(this, SmileyActivity.class);
    startActivity(i);
    }
}

ImageAdapter.class

    package de.retowaelchli.filterit.stats;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;


//import de.retowaelchli.filterit.SFilterConfigActivity;

public class ImageAdapter extends BaseAdapter {
    
    // references to our images
    private Integer[] mThumbIds;
    private Context mContext;
    
    
    public ImageAdapter(Context c, Integer[] imageIds) {
        mContext = c;
        mThumbIds = imageIds;
        
    }
    
    

    public int getCount() {
       return mThumbIds.length;
    }

    public Object getItem(int position) {
        return mThumbIds[position];
    }

    public long getItemId(int position) {
        return position;
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(final int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }
        
        imageView.setId(mThumbIds[position]);
        
        imageView.setImageResource(mThumbIds[position]);
       
        
        
        
        return imageView;
        
        
        
        
    }
    
}

このように、テキスト付きの写真をDBに追加しました。

   private void angry(){
        
        int drawableID = context.getResources().getIdentifier("angry", "drawable", getPackageName());
        iv.setImageResource(drawableID);
        
        //String info = String.valueOf(drawableID);
        String info = String.valueOf(drawableID);
        
        mDbHelper.open();
        
        mDbHelper.createSmiley("You received a angry message", info);
        
        mDbHelper.close();
    }

Log-Cat


そしてここにログがあります:

10-12 11:32:29.632: DEBUG/Database(25130): dbopen(): path = /data/data/de.retowaelchli.filterit/databases/filterit, flag = 6
10-12 11:32:29.632: DEBUG/Database(25130): dbopen(): path = /data/data/de.retowaelchli.filterit/databases/filterit, free size = 663
10-12 11:32:30.612: DEBUG/Database(25130): dbopen(): path = /data/data/de.retowaelchli.filterit/databases/filterit, flag = 6
10-12 11:32:30.612: DEBUG/Database(25130): dbopen(): path = /data/data/de.retowaelchli.filterit/databases/filterit, free size = 663
10-12 11:32:30.632: ERROR/Database(25130): Error inserting text=null smiley=null keyword=test name=test
10-12 11:32:30.632: ERROR/Database(25130): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
10-12 11:32:30.632: ERROR/Database(25130):     at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
10-12 11:32:30.632: ERROR/Database(25130):     at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:61)
10-12 11:32:30.632: ERROR/Database(25130):     at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1671)
10-12 11:32:30.632: ERROR/Database(25130):     at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1515)
10-12 11:32:30.632: ERROR/Database(25130):     at de.retowaelchli.filterit.database.SFilterDBAdapter.createSFilter(SFilterDBAdapter.java:89)
10-12 11:32:30.632: ERROR/Database(25130):     at de.retowaelchli.filterit.SFilterConfigActivity.onClickSConfigSave(SFilterConfigActivity.java:143)
10-12 11:32:30.632: ERROR/Database(25130):     at java.lang.reflect.Method.invokeNative(Native Method)
10-12 11:32:30.632: ERROR/Database(25130):     at java.lang.reflect.Method.invoke(Method.java:507)
10-12 11:32:30.632: ERROR/Database(25130):     at android.view.View$1.onClick(View.java:2186)
10-12 11:32:30.632: ERROR/Database(25130):     at android.view.View.performClick(View.java:2532)
10-12 11:32:30.632: ERROR/Database(25130):     at android.view.View$PerformClick.run(View.java:9277)
10-12 11:32:30.632: ERROR/Database(25130):     at android.os.Handler.handleCallback(Handler.java:587)
10-12 11:32:30.632: ERROR/Database(25130):     at android.os.Handler.dispatchMessage(Handler.java:92)
10-12 11:32:30.632: ERROR/Database(25130):     at android.os.Looper.loop(Looper.java:143)
10-12 11:32:30.632: ERROR/Database(25130):     at android.app.ActivityThread.main(ActivityThread.java:4196)
10-12 11:32:30.632: ERROR/Database(25130):     at java.lang.reflect.Method.invokeNative(Native Method)
10-12 11:32:30.632: ERROR/Database(25130):     at java.lang.reflect.Method.invoke(Method.java:507)
10-12 11:32:30.632: ERROR/Database(25130):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
10-12 11:32:30.632: ERROR/Database(25130):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
10-12 11:32:30.632: ERROR/Database(25130):     at dalvik.system.NativeStart.main(Native Method)

ここに私のSmileyDBAdapterのコードがあります。

SmileyDB

package de.retowaelchli.filterit.database;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class SmileyDBAdapter {
    
        public static final String ROW_ID = "_id";
        public static final String SOURCE = "source";
        public static final String INFO = "info";

        private static final String DATABASE_TABLE = "smiley";

        private DatabaseHelper mDbHelper;
        private SQLiteDatabase mDb;

        private final Context mCtx;

        private static class DatabaseHelper extends SQLiteOpenHelper {

            DatabaseHelper(Context context) {
                super(context, DBAdapter.DATABASE_NAME, null, DBAdapter.DATABASE_VERSION);
            }

            @Override
            public void onCreate(SQLiteDatabase db) {
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            }
        }

        /**
         * Constructor - takes the context to allow the database to be
         * opened/created
         * 
         * @param ctx
         *            the Context within which to work
         */
        public SmileyDBAdapter(Context ctx) {
            this.mCtx = ctx;
        }


        public SmileyDBAdapter open() throws SQLException {
            this.mDbHelper = new DatabaseHelper(this.mCtx);
            this.mDb = this.mDbHelper.getWritableDatabase();
            return this;
        }

        /**
         * close return type: void
         */
        public void close() {
            this.mDbHelper.close();
        }


        public long createSmiley(String source, String info ){
            ContentValues initialValues = new ContentValues();
            initialValues.put(SOURCE, source);
            initialValues.put(INFO, info);
            return this.mDb.insert(DATABASE_TABLE, null, initialValues);
        }


        public boolean deleteSmiley(long rowId) {

            return this.mDb.delete(DATABASE_TABLE, ROW_ID + "=" + rowId, null) > 0;
        }

        public Cursor getAllSmileys() {

            return this.mDb.query(DATABASE_TABLE, new String[] { ROW_ID,
                    SOURCE, INFO }, null, null, null, null, null);
        }
        


        
        //Es wird nach der ID des smiley gesucht.
        public Cursor getSmiley(String info) throws SQLException {

            Cursor mCursor =

            this.mDb.query(true, DATABASE_TABLE, new String[] { ROW_ID, SOURCE,
                    INFO }, INFO + "=" + info, null, null, null, null, null);
            if (mCursor != null) {
                mCursor.moveToFirst();
            }
            return mCursor;
        }


        public boolean updateSmiley(long rowId, String source, String info,
                String cache){
            ContentValues args = new ContentValues();
            args.put(SOURCE, source);
            args.put(INFO, info);

            return this.mDb.update(DATABASE_TABLE, args, ROW_ID + "=" + rowId, null) >0; 
        }

    }

DBAdapter

package de.retowaelchli.filterit.database;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBAdapter {

    public static final String DATABASE_NAME = "filterit";

    public static final int DATABASE_VERSION = 1;

    public static final String CREATE_TABLE_ADFILTER = "create table adfilter (_id integer primary key autoincrement, "
    + ADFilterDBAdapter.NAME+" not null ,"
    + ADFilterDBAdapter.KEYWORD+" not null ,"
    + ADFilterDBAdapter.CACHE + " not null );";

    private static final String CREATE_TABLE_SFILTER = "create table sfilter (_id integer primary key autoincrement, "
    +SFilterDBAdapter.NAME+" not null ,"
    +SFilterDBAdapter.KEYWORD+" not null ,"
    +SFilterDBAdapter.SMILEY+ " not null ,"
    +SFilterDBAdapter.TEXT+ " not null );";

    private static final String CREATE_TABLE_ADMESSAGES = "create table admessages (_id integer primary key autoincrement, "
    +MessagesDBAdapter.PHONENUMBER+" not null ,"
    +MessagesDBAdapter.MESSAGE+ " not null );";

    
    private static final String CREATE_TABLE_SMILEY = " create table smiley (_id integer primary key autoincrement, "
    +SmileyDBAdapter.SOURCE+" not null ,"
    +SmileyDBAdapter.INFO+ " not null );";
    
    
    private final Context context; 
    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    /**
     * Constructor
     * @param ctx
     */
    public DBAdapter(Context ctx)
    {
        this.context = ctx;
        
    }

    private static class DatabaseHelper extends SQLiteOpenHelper 
    {
        DatabaseHelper(Context context) 
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) 
        {
            db.execSQL(CREATE_TABLE_ADFILTER);
            db.execSQL(CREATE_TABLE_SFILTER);
            db.execSQL(CREATE_TABLE_ADMESSAGES);
            db.execSQL(CREATE_TABLE_SMILEY);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, 
        int newVersion) 
        {               
            // Adding any table mods to this guy here
        }
    } 

   /**
     * open the db
     * @return this
     * @throws SQLException
     * return type: DBAdapter
     */
    public DBAdapter open() throws SQLException 
    {
        this.DBHelper = new DatabaseHelper(this.context);
        this.db = this.DBHelper.getWritableDatabase();
        return this;
    }

    /**
     * close the db 
     * return type: void
     */
    public void close() 
    {
        this.DBHelper.close();
    }

}

4

4 に答える 4

2

サファリ、

コードを調べてエラーの原因を分析したところ、いくつかのことに気付きました。問題は、コードが行 ID とビュー ID を交換しようとしていることですが、これは実際には望ましい動作ではありません。

ではOnItemClick()id引数は を参照しrowIDます。(コードによって)一意であることが実際にrowIDは保証されていないため、失敗しています。を介して「問題を強制」することはできますがgetItemId()、その関数は単にオブジェクト (Integer) へのポインターを提供するだけです。これはあなたを苦しめるだけなので無視getItemId()してください。代わりに、ビュー自体を取得しviewIdて、次のように直接取得します。

編集 source = v.getId().toString(); 理由: TABLE は型を宣言していないため、文字列として入る可能性が最も高いです。ImageID が返されていることがわかり、データがそこにあることがわかります...だから、私が知る限り、型変換は残ります。

parent特にやviewのような入り組んだネストされたレイアウトでは、混乱を招くことがよくありGridViewsますListViews。ただし、 yourGridViewは非常に単純であり、そこに格納されているvを参照する必要があります。がまたは他の同様の親に保管されていたImageView場合、問題が発生する可能性がありますが、そのようなことはありません。ImageViewLinearLayout

これにより、 について心配する必要がなくなります。繰り返しますがgetItemId(int position)、これは特定のもの、特に各アイテムに固有のものrowIdを保証できる場合にのみ機能します。AdapterrowId

次に、値そのものではなく、viewIdのポインターに設定されます。IntegerAnintはプリミティブであるため、代入は期待どおりに行われます。AnIntegerObject、オブジェクト自体ではなく、オブジェクトのアドレスに対して代入が行われるためです。imageView.setId(mThumbIds[position]);(あなたのgetView())を次のように変更することをお勧めします:

   imageView.setId(mThumbIds[position].intValue());

これにより、メモリ内のオブジェクトへの参照ではなく、プリミティブint値が取得されます。Integerあなたのコードで他に何か間違ったことが起こっていない限り (そして私はすぐに何かを見ていない)、これで問題が解決するはずです。setId不適切なものidが割り当てられた場合、静かに失敗することを意図しているため、機能せず、単に通知しない場合があります。

最後に、「SOURCE」がコード内にあるフィールドのタイプがわかりません。実際のテーブルの作成は表示されません。したがって、特定のデータベースをさらに推測することは不可能です。お役に立てれば!

データベースについて データベース で際立っている主なものは、Simleys テーブルの CREATE TABLE ステートメントです。SQLite では、Type を明示的に割り当てない場合、SQLite はクエリを作成するたびに Type を決定し、フィールドにあるものに従って型を返します。これは、数値が文字列として解釈される可能性があり、その逆も同様であることを意味します。一般に、これはかなり信頼できるものですが、落とし穴につながる可能性があります。

コードにおける最大の問題の 1 つは、コードが意図したとおりに動作していると想定することです。実際、何をすべきかを正確に伝えた場合にのみ、これを保証できます。

次に、画像を取得して自分Array用に作成するImageAdapter場合INFOSOURCE. onItemClickを取得しているとに伝えると、これはコード内で誤解を招きますSOURCE。この変数名を変更することを検討してください。

次に、INFOを介してフィールドを照会するときに機能障害がありますgetSmiley(String info)。引数によると、整数ではなく文字列が必要です。Stringオブジェクトに を追加するContentValuesことは、整数を追加することとは異なります。AStringは '' で囲まれて追加され、'1' が 1 から分離IntegersされStringます。したがって、多くの変更が推奨されます。

  • まず、CREATE TABLE ステートメントを調整します。

    private static final String CREATE_TABLE_SMILEY = " create table smiley (_id integer primary key autoincrement, " +SmileyDBAdapter.SOURCE+" not null ," +SmileyDBAdapter.INFO+ " integer not null );";

このようにステートメントを変更すると、文字列ではなく整数を取得することが保証されます。

  • 次に、getImages()次のように変更しString infoItem = c.getString( ColumnIndex );ます。int infoItem = c.getInt( ColumnIndex );

  • 次に、 を に変更createSmiley(String source, String info)しますcreateSmiley(String source, int info)。これにより、すべてのインサートが正しく調整されます。オブジェクトContentValues( という名前initialValues) は何をすべきかを知っています。

  • 次に、 を に変更getSmiley(String info)しますgetSmiley(int info)。これにより、クエリも正しく調整されます。そうでない場合は、 に変更... + "=" + info + ...... + "=" + info.toString() + ...ます。これにより、問題が強制されます。

  • 次に、この行を次のように変更して一致onItemClick()させます。source = v.getId().toString();source = v.getId();

  • 最後にcreateSmiley()、文字列に変換された値ではなく、int 値を送信するように呼び出しを変更する必要があります。

これは、(実際にはそうではありませんが) 多くの変更を行う必要があります。したがって、これらの変更を行う前に、ソース ファイルをバックアップしてください。次に、パッケージをアンインストールして(エミュレートされている場合はエミュレーターからも含む)パッケージを再インストールするだけなので、元のデータは保持されません(整数ではなく文字列で)。

ファジカルロジック

于 2011-10-12T11:56:40.963 に答える
2

あなたのImageAdapterコードでは、メソッドgetItemidをオーバーライドして、問題を引き起こしている0を返しています.mThumbIds [position]を返してみてください。これでうまくいくと思います。

乾杯。

于 2011-10-07T08:43:15.843 に答える
1

getViewメソッドのImageAdapterクラスに、次のコード行を追加します

imageView.setId(mThumbIds[postion]);

または別のオプションは、クリックメソッド内のgridviewのOnclickリスナーにあります

source = (new Long(id)).toString();

このコード行を次のように置き換えます

source = parent.getItemId(position);

これで問題は確実に解決します。

于 2011-10-07T09:54:14.723 に答える
0

変化する

  if(c!=null)
    {

       while(c.moveToNext()){
           String infoItem = c.getString( ColumnIndex );
           infoList.add(Integer.parseInt(infoItem));
       }
    }

if(c!=null)
        {

           while(!c.isAfterLast()){
               String infoItem = c.getString( ColumnIndex );
               infoList.add(Integer.parseInt(infoItem));
               c.moveToNext();
           }
        }
于 2011-10-10T09:25:17.597 に答える