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

     2023-04-19     158

关键词:

【中文标题】在片段中显示适当的 SQLite 数据(相同的条目出现在不同的选择条目中)【英文标题】:Display appropriate SQLite data in fragment (same entry is appearing for different chosen entry) 【发布时间】:2018-07-25 17:27:30 【问题描述】:

好的,我正在尝试在我的应用程序中进行搜索查询,这将允许用户在找到正确的杂货项目结果后将其添加到另一个数据结构(最终成为食谱)。我还没有处理的添加组件...

现在我选择了 Button btnaddToRecipe 来启动 new 活动 AddGroceryItemActivity 被用户点击后(参见 CustomAdapter 活动了解该代码)。

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

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

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

问题:

当我去选择任何搜索结果时,点击 btnaddToRecipe 我会在一个新活动(AddGroceryItemActivity,它承载 AddGroceryItemFragment)中打开 same 搜索结果,其中包含我的一个数据库条目 -这与我选择的错误匹配。这与我选择的 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。

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

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

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

【问题讨论】:

【参考方案1】:

看来AddGroceryItemFragment 会按照以下方式从表中提取由所有行组成的游标:-

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 子句,以便它可以选择适当的杂货项目,而不是最后提取的(可能是任何)杂货项目。

查询可能是:-

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

我相信您会通过沿以下行添加额外的意图来传递凝视活动的 id(请参阅已添加的 1 行):-

@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 方法中传递的数据时,相同的光标是 无论我按什么按钮,都会通过。我想这是因为我 必须将光标标记为最终才能从匿名访问它 班级。这有意义吗?

您不必将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);
        
    );

【讨论】:

感谢您的回复。您写的内容在传递数据方面是有意义的,但是我仍然得到相同的结果。我在您编写查询时更改了查询,并在意图上添加了 putExtra()。然后,我检索您在片段中编写的 id,创建一个包对象,将字符串放入包中并使用 setArguments 方法将其添加到包中。我执行事务等并启动片段。然后从片段 @JCG 太好了。非常感谢您在已回答的问题上打勾。 抱歉,新手!我按了一个,但没有意识到有一个滴答声。再次感谢!

如何使用列表视图在选项卡式活动的片段中呈现 SQLite 表数据 [重复]

】如何使用列表视图在选项卡式活动的片段中呈现SQLite表数据[重复]【英文标题】:HowtorenderSQLitetabledatainafragmentoftabbedactivityusingListview[duplicate]【发布时间】:2017-08-0516:33:33【问题描述】:我正在尝试将SQLite数据库中的表数据显... 查看详情

如何在片段类的列表视图中显示 SQLite 数据库?

】如何在片段类的列表视图中显示SQLite数据库?【英文标题】:HowtodisplayaSQLitedatabaseinalistviewofafragmentclass?【发布时间】:2018-11-2102:58:58【问题描述】:我是AndroidStudio的新手。我有一个包含三列的SQLite数据库,我会将所有数据显... 查看详情

在firefox中浏览和编辑保存的表单数据(代码片段)

是否有人熟悉在Firefox中浏览和编辑/删除已保存表单条目的方法?我知道我可以:使用“清除隐私数据”对话框删除所有表单数据;当光标在它们上面时,使用shift-delete的形式的Deletespecificentries(*)。我想要的是一种查看特定关... 查看详情

如何在导航抽屉的片段上显示 SQLite 数据库数据?

】如何在导航抽屉的片段上显示SQLite数据库数据?【英文标题】:HowtodisplaySQLitedatabasedataonafragmentfromanavigationdrawer?【发布时间】:2018-04-1823:00:07【问题描述】:我正在努力使用导航抽屉显示内容。基本上我有一个显示五类面条的... 查看详情

如何在片段内的 recylerview 列表中显示 SQLite 数据库数据?

】如何在片段内的recylerview列表中显示SQLite数据库数据?【英文标题】:HowtoshowSQLitedatabasedatainarecylerviewlistwhichisinsideafragment?【发布时间】:2018-04-2415:35:54【问题描述】:我是一名业余android开发人员,我想从数据库中获取用户输... 查看详情

两个不同的joomla模块,显示相同的信息(代码片段)

我有一个显示来自Joomla表的信息的模块。该模块具有用于配置它的表单字段。问题是:当我使用适当的参数创建此模块的实例并将该模块显示在一个位置时,一切正常。现在,我取消发布该模块。我用其他参数创建了模块的第二... 查看详情

如何从 SQLite 中的表中选择最新的 100 个不同条目?

】如何从SQLite中的表中选择最新的100个不同条目?【英文标题】:Howtoselectthelatest100distinctentriesfromatableinSQLite?【发布时间】:2019-11-2013:29:16【问题描述】:尽管看起来很简单,但我一直在努力解决以下任务:从SQLite的表中选择最... 查看详情

具有相同名称的多个进程(代码片段)

我有一个在Linux2.6.13和WindRiverLinux3.0上运行的应用程序。在Linux2.6.13当我做...ps-eaf|grepmyapplication...输出显示'myapplication'的多个条目。如果我在WindRiverLinux3.0中提供相同的命令,输出只显示'myapplication'的一个条目差异与操作系统的差... 查看详情

刷新时如何防止重复条目?

...ollerservlet存储在数据库中。在数据库中输入数据后,我想显示与该表单相同的页面(index.jsp)。另外,我想显示用户在数据库中输入的所有条 查看详情

从列表条目访问 SQL 数据

...以下是我用于该计划的2个寡妇:主窗口输入窗口主窗口显示在程序的开头。我将QListWidget用于“宏”列表,它显示了从Sqlite数据库(DB)读取的每个条目的标题。当按下主窗口中的“新建”按钮时,会显 查看详情

node.jsmysql循环只显示最后一个条目(代码片段)

我已经看到这个问题并在这里得到了解答,但我似乎无法让它为我自己工作:我的javascriptmysql循环只显示数据库中的最后一个条目。我在电子中构建一个简单的内部wiki,我试图列出一些存储在mysql数据库中的类别。 <scri... 查看详情

如果与上一个条目相同,则不显示日期

】如果与上一个条目相同,则不显示日期【英文标题】:Don\'tDisplayDateifSameasPreviousEntry【发布时间】:2021-05-0620:04:24【问题描述】:我有一个条目列表,每个条目都附有日期。我只想在日期发生变化时才显示日期。我首先在iOS14.4... 查看详情

使用 `executemany` 更新现有 SQLite3 数据库中的条目(使用 Python sqlite3)

】使用`executemany`更新现有SQLite3数据库中的条目(使用Pythonsqlite3)【英文标题】:Using`executemany`toupdateentriesinanexistingSQLite3database(usingPythonsqlite3)【发布时间】:2016-02-2100:12:43【问题描述】:我知道executemany可用于方便地向数据库... 查看详情

编辑在 IOS 应用程序中管理的预填充 sqlite 数据库核心数据

】编辑在IOS应用程序中管理的预填充sqlite数据库核心数据【英文标题】:Editingapre-populatedsqlitedatabasecore-datamanagedinIOSapp【发布时间】:2011-10-3022:20:22【问题描述】:我想在我的应用中添加和删除新条目。当我添加或删除它时,它... 查看详情

如何在三重内连接表中显示适当的数据?

】如何在三重内连接表中显示适当的数据?【英文标题】:HowcanIdisplaytheappropriatedatainatripleinner-jointable?【发布时间】:2019-09-1619:01:43【问题描述】:我是SQL查询的新手,我正在尝试正确编写一个查询,以显示事件、它的信息以及... 查看详情

实体框架 6 和 SQLite - 无法创建条目 PK 之前删除的条目

】实体框架6和SQLite-无法创建条目PK之前删除的条目【英文标题】:EntityFramework6andSQLite-cannotcreateentrywithPKofentrydeletedbefore【发布时间】:2016-01-1714:17:38【问题描述】:我正在使用EntityFramework6和SQLite数据库(System.Data.SQLite.EF6),但删... 查看详情

Android 日记应用 - 搜索 SQLite 数据库并在 ListView 中显示结果

】Android日记应用-搜索SQLite数据库并在ListView中显示结果【英文标题】:Androiddiaryapp-SearchSQLitedatabaseanddisplayresultsinListView【发布时间】:2021-10-0507:00:47【问题描述】:我在Android中有一个日记应用程序,我希望能够根据用户在EditTex... 查看详情

sql在选项表中选择autoloadtrue的大型数据库条目,以字节为单位显示大小#optimization#database#wordpress(代码片段)

查看详情