在片段中显示适当的SQLite数据(不同的选择条目出现相同的条目)

时间:2018-02-15 02:07:52

标签: android sqlite android-fragments cursors

好吧我正在尝试做的是在我的应用程序中有一个搜索查询,这将允许用户在找到正确的杂货项目结果后将其添加到另一个数据结构(最终是一个配方)。添加组件我还没有工作......

现在我已选择Button btnaddToRecipe开始活动  被用户点击后 AddGroceryItemActivity (请参阅该代码的CustomAdapter活动)。

这个新活动将打开其片段,其中将进行一些计算,当我开始计算时,将创建/修改新的数据结构以允许用户添加该杂货项目到具有所需项目数量的数据结构。

有关杂货商品名称的数据,以及Grams-Cups和Cups-Grams转换比率(存储在我的数据库中)需要传递到这个新片段以进行计算(取决于什么用户将选择输入)。

(您可以在我的搜索查询代码中查看数据库列)

问题:

当我选择任何搜索结果时,点击btnaddToRecipe我会在我的一个数据库条目的新活动(AddGroceryItemActivity,托管AddGroceryItemFragment)中打开相同搜索结果 - 这与我选择的那个不匹配。这与我选择的错误输入 EVERY 选项相同。

所以我认为这与我的光标循环遍历AddGroceryItemFragment中的选项的方式有关。

或者是因为我没有将关于用户选择的搜索结果的正确数据传递给新活动。

要显示的片段类:

public class AddGroceryItemFragment extends Fragment {
private static final String TAG = "AddGroceryItemFragment";

private OnSaveClicked mSaveListener;
private AppDatabase dbHelper;

interface OnSaveClicked {
    void onSaveClicked();
}


@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Log.d(TAG, "onAttach: starts");

    dbHelper = AppDatabase.getInstance(context);

    Activity activity = getActivity();
    if (!(activity instanceof OnSaveClicked)) {
        throw new ClassCastException(activity.getClass().getSimpleName()
                + " must implement AddGrocerItemFragment.OnSaveClicked interface");
    }

    mSaveListener = (OnSaveClicked) activity;

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.d(TAG, "onCreateView: starts");
    View view = inflater.inflate(R.layout.fragment_addgroceryitem, container, false);
    final ViewHolder holder = new ViewHolder();
    holder.mCalculate = (Button) view.findViewById(R.id.calculate);
    holder.mAddToList = (Button) view.findViewById(R.id.addToList);
    holder.mCupsToGrams = (TextView) view.findViewById(R.id.CupsToG);
    holder.mGramsToCups = (TextView) view.findViewById(R.id.gToCups);
    holder.name = (TextView) view.findViewById(R.id.name);
    holder.mQuantity = (EditText) view.findViewById(R.id.entry);

    SQLiteDatabase db = dbHelper.getReadableDatabase();
    String selectQuery = "SELECT rowid as " +
            GroceriesContract.Columns._ID + ", " +
            GroceriesContract.Columns.GROCERIES_NAME + ", " +
            GroceriesContract.Columns.GROCERIES_DESCRIPTION + ", " +
            GroceriesContract.Columns.GROCERIES_GRAMSTOCUPS + ", " +
            GroceriesContract.Columns.GROCERIES_CUPSTOGRAMS +
            " FROM " + GroceriesContract.TABLE_NAME;
    Cursor cursor = db.rawQuery(selectQuery, null);


    if (cursor.moveToFirst()) {
        do {
            holder.name.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_NAME)));
            holder.mGramsToCups.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_GRAMSTOCUPS)));
            holder.mCupsToGrams.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_GRAMSTOCUPS)));
        } while (cursor.moveToNext());
    }
        cursor.close();

 return view;
}


static class ViewHolder {
    TextView name;
    EditText mQuantity;
    Button mCalculate;
    Button mAddToList;
    TextView mGramsToCups;
    TextView mCupsToGrams;
}

片段的行为:

public class AddEditRecipeActivity extends AppCompatActivity implements AddEditRecipeActivityFragment.OnSaveClicked {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_edit_recipe);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    AddEditRecipeActivityFragment fragment = new 
AddEditRecipeActivityFragment();
    Bundle arguments = getIntent().getExtras();
    fragment.setArguments(arguments);

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = 
fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.fragment, fragment);
    fragmentTransaction.commit();
}

@Override
public void onSaveClicked() {
    finish();
}

}

您可以看到启动活动的按钮 - 是否需要拉出此光标信息?

public class SearchActivity extends AppCompatActivity {
   private static final String TAG = "SearchActivity";

private Cursor mCursor;
private CustomAdapter mCustomAdapter;
private GroceriesContract mGroceriesContract;
ListView mListView;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_search);


    mGroceriesContract = new GroceriesContract(this);
    mCursor = mGroceriesContract.getGroceryList();
    mCustomAdapter = new CustomAdapter(SearchActivity.this, mCursor, 0);
    mListView = (ListView) findViewById(R.id.lstStudent);
    mListView.setAdapter(mCustomAdapter);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.options_menu, menu);
    SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();
    search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);


    search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            Log.d(TAG, "onQueryTextSubmit: on");
            mCursor = mGroceriesContract.getGroceryName(query);
            if (mCursor == null) {
                Toast.makeText(SearchActivity.this, "No records found", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(SearchActivity.this, mCursor.getCount() + " records found!", Toast.LENGTH_SHORT).show();
            }

            mCustomAdapter.swapCursor(mCursor);

            return false;

        }

        @Override
        public boolean onQueryTextChange(String newText) {
            Log.d(TAG, "onQueryTextChange: ");
            mCursor = mGroceriesContract.getGroceryName(newText);
            if (mCursor != null) {
                mCustomAdapter.swapCursor(mCursor);
            }
            return false;
        }
    });


    return true;

}

@Override
protected void onResume() {
    super.onResume();
 }
}

我想知道这个问题是否实际上是由于没有从启动此活动的活动传递数据导致启动 AddGroceryItemFragment

这个初始类扩展了CursorAdapter:

public class CustomAdapter extends CursorAdapter {
TextView txtId,txtName, txtDescription;
private LayoutInflater mInflater;
private Context mContext;

public CustomAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}


@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    View view    =    mInflater.inflate(R.layout.item, parent, false);
    ViewHolder holder  =   new ViewHolder();
    holder.txtId    =   (TextView)  view.findViewById(R.id.txtId);
    holder.txtName    =   (TextView)  view.findViewById(R.id.txtName);
    holder.txtDescription =   (TextView)  view.findViewById(R.id.txtEmail);
    holder.btnaddToRecipe = (Button) view.findViewById(R.id.add);
    view.setTag(holder);


    return view;
}

@Override
public void bindView(View view, final Context context, final Cursor cursor) {

    ViewHolder holder  =   (ViewHolder)    view.getTag();
    holder.txtId.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns._ID)));
    holder.txtName.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_NAME)));
    holder.txtDescription.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_DESCRIPTION)));

    holder.btnaddToRecipe.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(context, AddGroceryItemActivity.class);
            context.startActivity(intent);
        }
    });

}

static class ViewHolder {
    TextView txtId;
    TextView txtName;
    TextView txtDescription;
    Button btnaddToRecipe;
 }
}

新编辑: 谢谢你的回复MikeT。

你所写的内容在传递数据方面是有意义的,但每次我仍然得到相同的结果。我在编写时更改了查询,并在intent上添加了putExtra()。然后我在片段中编写它时检索id,创建一个bundle对象,将字符串放入bundle中并使用setArguments方法将其添加到bundle中。我执行事务等开始片段。然后从片段中,我创建了一个新字符串并调用了getArguments()。getString(“id”)。将whereargs设置为新字符串并按照您的说法编写查询。

我认为这是我的光标代码的编写方式。我正在意识到mCupsToGrams上的拼写错误 - 应该是GROCERIES_CUPSTOGRAMS。但这与这个问题无关。

当我登录我在 onClick 方法中传递的数据时,无论我按哪个按钮,都会传递相同的光标。我认为这是因为我必须将光标标记为 final 才能从匿名类访问它。那有意义吗?

1 个答案:

答案 0 :(得分:0)

AddGroceryItemFragment似乎从表中提取一个由表中所有行组成的Cursor: -

SQLiteDatabase db = dbHelper.getReadableDatabase();
String selectQuery = "SELECT rowid as " +
        GroceriesContract.Columns._ID + ", " +
        GroceriesContract.Columns.GROCERIES_NAME + ", " +
        GroceriesContract.Columns.GROCERIES_DESCRIPTION + ", " +
        GroceriesContract.Columns.GROCERIES_GRAMSTOCUPS + ", " +
        GroceriesContract.Columns.GROCERIES_CUPSTOGRAMS +
        " FROM " + GroceriesContract.TABLE_NAME;
Cursor cursor = db.rawQuery(selectQuery, null);

然后循环遍历每个提取的行,设置要显示的文本,从而使显示最终显示最后提取的行的数据。

我相信您需要在查询中使用WHERE子句,以便它可以选择适当的Grocery Item而不是最后提取的(可能是任何)杂货项目。

查询可以是: -

String[] columns = new String[]{
    "rowid AS " +
        GroceriesContract.Columns._ID,
    GroceriesContract.Columns.GROCERIES_NAME,
    GroceriesContract.Columns.GROCERIES_DESCRIPTION,
    GroceriesContract.Columns.GROCERIES_GRAMSTOCUPS,
    GroceriesContract.Columns.GROCERIES_CUPSTOGRAMS
};
String whereclause = GroceriesContract.Columns._ID + "=?";
String[] whereargs = new String[]{the_id_passed_to_the_fragment};
Cursor cursor =db.query(GroceriesContract.TABLE_NAME,columns,whereclause,whereargs,null,null,null);
    • 这使用首选query方法,而不是rawQuery query
    • 变量 the_id_passed_to_the_fragment 正如其名称所示,正如您怀疑或者它是因为我没有传递有关用户选择的搜索结果的正确数据,到了新活动。和/或我想知道这个问题是否实际上是因为没有从启动此活动的活动传递数据然后导致启动AddGroceryItemFragment

你会跟着这个: -

if (cursor.moveToFirst()) {
    holder.name.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_NAME)));
    holder.mGramsToCups.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_GRAMSTOCUPS)));
    holder.mCupsToGrams.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_GRAMSTOCUPS)));
}
else {
    //... do something just in case Grocery Item wasn't found here.
}
cursor.close();

我相信你会通过添加一个额外的意图(看到已添加的1行)来从凝视活动中传递id: -

@Override
public void bindView(View view, final Context context, final Cursor cursor) {

    ViewHolder holder  =   (ViewHolder)    view.getTag();
    holder.txtId.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns._ID)));
    holder.txtName.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_NAME)));
    holder.txtDescription.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_DESCRIPTION)));

    holder.btnaddToRecipe.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(context, AddGroceryItemActivity.class);
            intent.putExtra("GROCERYITEMID",cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns._ID))); //<<<< ADDED
            context.startActivity(intent);
        }
    });
}

您可以使用以下方法在已启动的活动中检索此内容: -

 String retrieved_id = getIntent().getStringExtra(
            "GROCERYITEMID");

然后,您需要以 retrieved_id 为片段提供 the_id_passed_to_the_fragment

关于评论: -

  

当我记录在onClick方法中传递的数据时,同样的光标是   无论我按什么按钮都被传递。我想这是因为我   必须将光标标记为final才能从匿名访问它   类。这有意义吗?

您不必将cursor标记为final,而是使用以下内容: -

@Override
public void bindView(View view, Context context, Cursor cursor) {

    ViewHolder holder  =   (ViewHolder)    view.getTag();
    holder.txtId.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns._ID)));
    holder.txtName.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_NAME)));
    holder.txtDescription.setText(cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns.GROCERIES_DESCRIPTION)));
    final String id_to pass = cursor.getString(cursor.getColumnIndex(GroceriesContract.Columns._ID));

    holder.btnaddToRecipe.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(context, AddGroceryItemActivity.class);
            intent.putExtra("GROCERYITEMID",id_to pass); //<<<< ADDED
            context.startActivity(intent);
        }
    });
}