- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
似乎无法弄清楚这一点,我已经浏览了所有代码但没有成功。当我将新的投球手添加到空列表时,它会正确显示,当我向列表中添加第二个或更多投球手时,投球手的名称显示为添加的第一个投球手的名称。我在下面添加了几张屏幕截图来说明我的意思。
显然这些图像的顺序是从左到右。我也将我的 BowlerActivity 包含在这篇文章中。这是我创建和更新新的和现有的保龄球手的地方。
private BowlerAdapter mAdapter;
private List<Bowler> bowlersList = new ArrayList<>();
private CoordinatorLayout coordinatorLayout;
private RecyclerView recyclerView;
private TextView noBowlersView;
private DatabaseHelper db;
private TextView leagueId;
private String savedLeagueId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bowler);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),MainActivity.class));
finish();
}
});
savedLeagueId = String.valueOf(getIntent().getIntExtra("leagueId",2));
leagueId = (TextView) findViewById(R.id.tvLeagueId);
coordinatorLayout = findViewById(R.id.coordinator_layout);
recyclerView = findViewById(R.id.recycler_view);
noBowlersView = findViewById(R.id.empty_bowlers_view);
db = new DatabaseHelper(this);
bowlersList.addAll(db.getAllBowlers(savedLeagueId));
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.add_bowler_fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showBowlerDialog(false, null, -1);
}
});
mAdapter = new BowlerAdapter(this, bowlersList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
recyclerView.setAdapter(mAdapter);
toggleEmptyBowlers();
//On Long Click On The RecyclerView Item An Alert Dialog Is Opened With The Option To Choose Edit/Delete
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this,
recyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, final int position) {
String seriesLeagueId = bowlersList.get(position).getLeagueId();
int seriesBowlerId = bowlersList.get(position).getId();
Intent myIntent = new Intent(BowlerActivity.this, SeriesActivity.class);
myIntent.putExtra("seriesLeagueId", seriesLeagueId);
myIntent.putExtra("seriesBowlerId", seriesBowlerId);
startActivity(myIntent);
}
@Override
public void onLongClick(View view, int position) {
showActionsDialog(position);
}
}));
}
//Inserting New Bowler In The Database And Refreshing The List
private void createBowler(String leagueId, String bowlerName) {
//Inserting Bowler In The Database And Getting Newly Inserted Bowler Id
long id = db.insertBowler(leagueId, bowlerName);
//Get The Newly Inserted Bowler From The Database
Bowler n = db.getBowler(leagueId);
if (n != null) {
//Adding New Bowler To The Array List At Position 0
bowlersList.add(0, n);
//Refreshing The List
mAdapter.notifyDataSetChanged();
toggleEmptyBowlers();
}
}
//Updating Bowler In The Database And Updating The Item In The List By Its Position
private void updateBowler(String bowlerName, int position) {
Bowler n = bowlersList.get(position);
//Updating Bowler Text
n.setLeagueId(savedLeagueId);
n.setName(bowlerName);
//Updating The Bowler In The Database
db.updateBowler(n);
//Refreshing The List
bowlersList.set(position, n);
mAdapter.notifyItemChanged(position);
toggleEmptyBowlers();
}
//Deleting Bowler From SQLite Database And Removing The Bowler Item From The List By Its Position
private void deleteBowler(int position) {
//Deleting The Bowler From The Database
db.deleteBowler(bowlersList.get(position));
//Removing The Bowler From The List
bowlersList.remove(position);
mAdapter.notifyItemRemoved(position);
toggleEmptyBowlers();
}
//Opens Dialog With Edit/Delete Options
//Edit - 0
//Delete - 0
private void showActionsDialog(final int position) {
CharSequence colors[] = new CharSequence[]{"Edit", "Delete"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose option");
builder.setItems(colors, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
showBowlerDialog(true, bowlersList.get(position), position);
} else {
deleteBowler(position);
}
}
});
builder.show();
}
//Show Alert Dialog With EditText Options to Enter/Edit A League
//When shouldUpdate = true, It Will Automatically Display Old Bowler Name And Change The Button Text To UPDATE
private void showBowlerDialog(final boolean shouldUpdate, final Bowler bowler, final int position) {
LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
View view = layoutInflaterAndroid.inflate(R.layout.dialog_bowler, null);
AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(BowlerActivity.this);
alertDialogBuilderUserInput.setView(view);
leagueId.setText(savedLeagueId);
final EditText inputBowlerName = view.findViewById(R.id.etBowlerNameInput);
TextView dialogTitle = view.findViewById(R.id.dialog_title);
dialogTitle.setText(!shouldUpdate ? getString(R.string.lbl_new_bowler_title) : getString(R.string.lbl_edit_bowler_title));
if (shouldUpdate && bowler != null) {
leagueId.setText(bowler.getLeagueId());
inputBowlerName.setText(bowler.getName());
}
alertDialogBuilderUserInput
.setCancelable(false)
.setPositiveButton(shouldUpdate ? "update" : "save", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
}
})
.setNegativeButton("cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
dialogBox.cancel();
}
});
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Show Toast Message When No Text Is Entered
if (TextUtils.isEmpty(inputBowlerName.getText().toString())) {
Toast.makeText(BowlerActivity.this, "Enter Bowler!", Toast.LENGTH_SHORT).show();
return;
} else {
alertDialog.dismiss();
}
//Check If User Is Updating Bowler
if (shouldUpdate && bowler != null) {
//Updating Bowler By Its Id
updateBowler(inputBowlerName.getText().toString(), position);
} else {
//Creating New Bowler
createBowler(leagueId.getText().toString(), inputBowlerName.getText().toString());
}
}
});
}
//Toggling List And Empty Bowler View
private void toggleEmptyBowlers() {
//You Can Check bowlerList.size() > 0
if (db.getBowlersCount() > 0) {
noBowlersView.setVisibility( View.GONE);
} else {
noBowlersView.setVisibility( View.VISIBLE);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate( R.menu.menu_main, menu );
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected( item );
}
}
我还包含了包含 Bowler 方法的 DatabaseHelper 部分。
public long insertBowler(String leagueId, String bowlerName) {
//Get Writable Database That We Want To Write Data Too
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
//`id` and `timestamp` Will Be Inserted Automatically
values.put(Bowler.COLUMN_LEAGUE_ID, leagueId);
values.put(Bowler.COLUMN_NAME, bowlerName);
//Insert Row
long id = db.insert( Bowler.TABLE_NAME, null, values );
//Close Database Connection
db.close();
//Return Newly Inserted Row Id
return id;
}
public Bowler getBowler(String leagueId) {
//Get Readable Database If We Are Not Inserting Anything
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(Bowler.TABLE_NAME,
new String[]{Bowler.COLUMN_ID, Bowler.COLUMN_LEAGUE_ID, Bowler.COLUMN_NAME, Bowler.COLUMN_TIMESTAMP},
Bowler.COLUMN_LEAGUE_ID + "=?",
new String[]{String.valueOf(leagueId)}, null, null, null, null);
if (cursor.moveToFirst()) {
//Prepare Bowler Object
Bowler bowler = new Bowler(
cursor.getInt(cursor.getColumnIndex(Bowler.COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_NAME)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));
//Close Database Connection
cursor.close();
return bowler;
} else {return null;}
}
public List<Bowler> getAllBowlers(String leagueId) {
List<Bowler> bowlers = new ArrayList<>();
//Select All Query
String selectQuery = "SELECT * FROM " + Bowler.TABLE_NAME + " WHERE " + Bowler.COLUMN_LEAGUE_ID + " = '" + leagueId + "'" + " ORDER BY " +
Bowler.COLUMN_TIMESTAMP + " DESC";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
//Looping Through All Rows And Adding To The List
if (cursor.moveToFirst()) {
do {
Bowler bowler = new Bowler();
bowler.setId(cursor.getInt(cursor.getColumnIndex(Bowler.COLUMN_ID)));
bowler.setLeagueId(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)));
bowler.setName(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_NAME)));
bowler.setTimestamp(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));
bowlers.add(bowler);
} while (cursor.moveToNext());
}
cursor.close();
//Close Database Connection
db.close();
//Return Bowlers List
return bowlers;
}
public int getBowlersCount() {
String countQuery = "SELECT * FROM " + Bowler.TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
//Return The Count
return count;
}
public int updateBowler(Bowler bowler) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Bowler.COLUMN_LEAGUE_ID, bowler.getLeagueId());
values.put(Bowler.COLUMN_NAME, bowler.getName());
//Updating Row
return db.update(Bowler.TABLE_NAME, values, Bowler.COLUMN_ID + " = ?",
new String[]{String.valueOf(bowler.getId())});
}
public void deleteBowler(Bowler bowler) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete( Bowler.TABLE_NAME, Bowler.COLUMN_ID + " = ?",
new String[]{String.valueOf( bowler.getId())});
db.close();
}
为了以防万一,我也发布了 BowlerAdapter 代码。
public class BowlerAdapter extends RecyclerView.Adapter<BowlerAdapter.MyViewHolder> {
private Context context;
private List<Bowler> bowlersList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView bowlerLeagueId;
public TextView name;
public TextView timestamp;
public MyViewHolder(View view) {
super(view);
bowlerLeagueId = view.findViewById( R.id.tvLeagueId);
name = view.findViewById(R.id.tvBowlerName );
timestamp = view.findViewById(R.id.timestamp);
}
}
public BowlerAdapter(Context context, List<Bowler> bowlersList) {
this.context = context;
this.bowlersList = bowlersList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listview_bowler, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Bowler bowler = bowlersList.get(position);
holder.bowlerLeagueId.setText(bowler.getLeagueId());
holder.name.setText(bowler.getName());
//Formatting And Displaying Timestamp
holder.timestamp.setText(formatDate(bowler.getTimestamp()));
}
@Override
public int getItemCount() {
return bowlersList.size();
}
//Formatting TimeStamp to 'EEE MMM dd yyyy (HH:mm:ss)'
//Input : 2018-05-23 9:59:01
//Output : Wed May 23 2018 (9:59:01)
private String formatDate(String dateStr) {
try {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = fmt.parse(dateStr);
SimpleDateFormat fmtOut = new SimpleDateFormat("EEE MMM dd yyyy (HH:mm:ss)");
return fmtOut.format(date);
} catch (ParseException e) { }
return "";
}
我确信这是非常明显的事情,但我已经查看代码几个小时了,但我只是没有看到问题。
如有任何帮助,我们将不胜感激。
我已经按照您的指示修改了我的代码,但是当我添加一个新的 Bowler 时,屏幕会返回空白,直到我离开 BowlerActivity 并返回其中,此时列表已更新。
//Inserting New Bowler In The Database And Refreshing The List
private void createBowler(String leagueId, String bowlerName) {
//Inserting Bowler In The Database And Getting Newly Inserted Bowler Id
long id = db.insertBowler(leagueId, bowlerName);
//Get The Newly Inserted Bowler From The Database
Bowler n = db.getBowler(leagueId);
if (n != null) {
//Adding New Bowler To The Array List At Position 0
bowlersList.add(0, n);
//Refreshing The List
mAdapter.notifyDataSetChanged(bowlersList);
toggleEmptyBowlers();
}
}
BowlerAdapter 的notifyDataSetChanged 方法
private List<Bowler> bowlersList;
public void notifyDataSetChanged(List<Bowler> newbowlersList) {
bowlersList.clear();
bowlersList.addAll( newbowlersList );
super.notifyDataSetChanged();
}
调试日志
this = {BowlerActivity@5027}
leagueId = "1"
bowlerName = "Robert"
id = 6
n = {Bowler@5032}
id = 1
league_id = "1"
name = "b1"
timestamp = "2018-06-07 20:03:19"
shadow$_klass_ = {Class@4839} "class ca.rvogl.tpbcui.database.models.Bowler"
shadow$_monitor_ = -2106571381
mAdapter = {BowlerAdapter@5033}
bowlersList = {ArrayList@5037} size = 0
mHasStableIds = false
mObservable = {RecyclerView$AdapterDataObservable@5088}
shadow$_klass_ = {Class@4930} "class ca.rvogl.tpbcui.views.BowlerAdapter"
shadow$_monitor_ = -2088753560
log.d 日志文件 fragment
06-08 13:00:53.807 29879-29879/ca.rvogl.tpbcui D/INSERTBOWLER: Number of bowlers in db = 4
06-08 13:00:53.814 29879-29884/ca.rvogl.tpbcui I/art: Do partial code cache collection, code=30KB, data=29KB
06-08 13:00:53.815 29879-29884/ca.rvogl.tpbcui I/art: After code cache collection, code=30KB, data=29KB
Increasing code cache capacity to 128KB
06-08 13:00:53.815 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:00:53.831 29879-29879/ca.rvogl.tpbcui W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
06-08 13:01:00.552 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:02.336 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:04.023 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:04.040 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:04.050 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:04.059 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:04.534 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:04.542 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:05.034 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:11.363 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:11.373 29879-29879/ca.rvogl.tpbcui D/INSERTBOWLER: Number of bowlers in db = 5
06-08 13:01:11.380 29879-29895/ca.rvogl.tpbcui D/EGL_emulation: eglMakeCurrent: 0x9e6fa300: ver 3 0 (tinfo 0xa068a610)
06-08 13:01:11.393 29879-29879/ca.rvogl.tpbcui W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
最佳答案
我认为您的问题是您没有更新适配器内的实际源列表。
解决方案可能是向 BowlerAdapter 添加一个方法,例如:-
public void notifyDatasetChanged(List<Bowler> newbowlerlist) {
bowlersList.clear();
bowlersList.addAll(newbowlerlist);
super.notifyDataSetChanged();
}
然后使用这个新方法,传递修改后的bowlerlist,而不是库存的notifyDatasetChanged 方法。
例如而不是:-
if (n != null) {
//Adding New Bowler To The Array List At Position 0
bowlersList.add(0, n);
//Refreshing The List
mAdapter.notifyDataSetChanged();
toggleEmptyBowlers();
}
使用:-
if (n != null) {
//Adding New Bowler To The Array List At Position 0
bowlersList.add(0, n);
//Refreshing The List
mAdapter.notifyDataSetChanged(bowlerList);
toggleEmptyBowlers();
}
根据您使用上述代码的代码,获得以下结果:-
初始显示
添加新投球手后
添加了一个新的投球手:-
:-
添加评论:-
OK, insert is happening OK (you can remove the changes). Now make the following changes to the
getAllBowlers
method (1 write the selectQuery sql to the log, 2 write the number of rows retrieved to the log and 3 write the size of the bowlers ArrayList to the log). Run and report or fix.
public List<Bowler> getAllBowlers(String leagueId) {
List<Bowler> bowlers = new ArrayList<>();
//Select All Query
String selectQuery = "SELECT * FROM " + Bowler.TABLE_NAME + " WHERE " + Bowler.COLUMN_LEAGUE_ID + " = '" + leagueId + "'" + " ORDER BY " +
Bowler.COLUMN_TIMESTAMP + " DESC";
Log.d("GETALLBOWLERS-SQL","SQL used = >>>>" +selectQuery + "<<<<");
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
Log.d("GETALLBOWLERS-CNT","Number of rows retrieved = " + String.valueOf(cursor.getCount()));
//Looping Through All Rows And Adding To The List
if (cursor.moveToFirst()) {
do {
Bowler bowler = new Bowler();
bowler.setId(cursor.getInt(cursor.getColumnIndex(Bowler.COLUMN_ID)));
bowler.setLeagueId(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)));
bowler.setName(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_NAME)));
bowler.setTimestamp(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));
bowlers.add(bowler);
} while (cursor.moveToNext());
}
cursor.close();
//Close Database Connection
db.close();
Log.d("GETALLBOWLERS-CNT","Number of elements in bowlerslist = " + String.valueOf(bowlers.size()));
//Return Bowlers List
return bowlers;
}
<小时/>
我实际上无法指出您的问题,尽管我确实相信它与原始答案有关,因为适配器在投球手列表的副本上工作/与投球手列表的副本一起工作,这与传递给它的投球手列表不同。因此,更改 Activity 中的投球手列表不会更改适配器中的投球手列表。因此发布 onNotifyDatasetChanged
更改 Bowlerlist 后,就是向适配器表明您已更改适配器中的列表(即,它是副本,尚未更改)。
因此,投球手列表上的副本必须更改,然后 onNotifyDatasetChanged
应发出。我的猜测是您没有正确实现上述内容。
因此,我几乎重新创建了您的代码并拥有一个可以工作的版本:-
public class BowlerActivity extends AppCompatActivity {
private BowlerAdapter mAdapter;
private List<Bowler> bowlersList = new ArrayList<>();
private RecyclerView recyclerView;
private DatabaseHelper db;
private Button addbowler;
private EditText newbowler;
private TextView leagueId, noBowlersView;
private String savedLeagueId;
Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
addbowler = this.findViewById(R.id.addbowler); // For testing
leagueId = this.findViewById(R.id.tvLeagueId);
noBowlersView = this.findViewById(R.id.noBowlersView);
recyclerView = this.findViewById(R.id.recycler_view);
db = new DatabaseHelper(this);
savedLeagueId = "0"; //<<<< HARD CODED rather than get from IntentExtra
leagueId.setText(savedLeagueId);
bowlersList = db.getAllBowlers(leagueId.getText().toString());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
mAdapter = new BowlerAdapter(this,bowlersList);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
//recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
recyclerView.setAdapter(mAdapter);
addbowler.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showBowlerDialog(false, null, -1);
}
});
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
Toast.makeText(mContext,"You clicked me", Toast.LENGTH_SHORT).show();
}
@Override
public void onLongClick(View view, int position) {
Toast.makeText(mContext,"You long clicked me", Toast.LENGTH_SHORT).show();
showActionsDialog(position);
}
}));
}
//Opens Dialog With Edit/Delete Options
//Edit - 0
//Delete - 0
private void showActionsDialog(final int position) {
CharSequence colors[] = new CharSequence[]{"Edit", "Delete"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose option");
builder.setItems(colors, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
showBowlerDialog(true, bowlersList.get(position), position);
} else {
deleteBowler(position);
}
}
});
builder.show();
}
//Toggling List And Empty Bowler View
private void toggleEmptyBowlers() {
//You Can Check bowlerList.size() > 0
if (db.getBowlersCount() > 0) {
noBowlersView.setVisibility( View.GONE);
} else {
noBowlersView.setVisibility( View.VISIBLE);
}
}
//Inserting New Bowler In The Database And Refreshing The List
private void createBowler(String leagueId, String bowlerName) {
//Inserting Bowler In The Database And Getting Newly Inserted Bowler Id
long id = db.insertBowler(leagueId, bowlerName);
//Get The Newly Inserted Bowler From The Database
bowlersList = db.getAllBowlers(leagueId);
mAdapter.notifyDatasetChanged(bowlersList);
//mAdapter.notifyDataSetChanged();
}
//Updating Bowler In The Database And Updating The Item In The List By Its Position
private void updateBowler(String bowlerName, int position) {
Bowler n = bowlersList.get(position);
//Updating Bowler Text
n.setLeagueId(savedLeagueId);
n.setName(bowlerName);
//Updating The Bowler In The Database
db.updateBowler(n);
//Refreshing The List
bowlersList.set(position, n); //<<<<< does not change the bowlerlist in the adapter
//mAdapter.notifyItemChanged(position); // Saying that nothing has changed
mAdapter.notifyDatasetChanged(db.getAllBowlers(savedLeagueId)); //<<<<< rebuilds adapter bowler list
toggleEmptyBowlers();
}
//Deleting Bowler From SQLite Database And Removing The Bowler Item From The List By Its Position
private void deleteBowler(int position) {
//Deleting The Bowler From The Database
db.deleteBowler(bowlersList.get(position));
//Removing The Bowler From The List
bowlersList.remove(position);
//mAdapter.notifyItemRemoved(position); // Saying that nothing has changed
mAdapter.notifyDatasetChanged(db.getAllBowlers(savedLeagueId));
toggleEmptyBowlers();
}
public interface ClickListener{
void onClick(View view,int position);
void onLongClick(View view,int position);
}
//Show Alert Dialog With EditText Options to Enter/Edit A League
//When shouldUpdate = true, It Will Automatically Display Old Bowler Name And Change The Button Text To UPDATE
private void showBowlerDialog(final boolean shouldUpdate, final Bowler bowler, final int position) {
LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
View view = layoutInflaterAndroid.inflate(R.layout.dialog_bowler, null);
AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(BowlerActivity.this);
alertDialogBuilderUserInput.setView(view);
leagueId.setText(savedLeagueId);
final EditText inputBowlerName = view.findViewById(R.id.etBowlerNameInput);
TextView dialogTitle = view.findViewById(R.id.dialog_title);
dialogTitle.setText(!shouldUpdate ? getString(R.string.lbl_new_bowler_title) : getString(R.string.lbl_edit_bowler_title));
if (shouldUpdate && bowler != null) {
leagueId.setText(bowler.getLeagueId());
inputBowlerName.setText(bowler.getName());
}
alertDialogBuilderUserInput
.setCancelable(false)
.setPositiveButton(shouldUpdate ? "update" : "save", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
}
})
.setNegativeButton("cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
dialogBox.cancel();
}
});
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Show Toast Message When No Text Is Entered
if (TextUtils.isEmpty(inputBowlerName.getText().toString())) {
Toast.makeText(BowlerActivity.this, "Enter Bowler!", Toast.LENGTH_SHORT).show();
return;
} else {
alertDialog.dismiss();
}
//Check If User Is Updating Bowler
if (shouldUpdate && bowler != null) {
//Updating Bowler By Its Id
updateBowler(inputBowlerName.getText().toString(), position);
} else {
//Creating New Bowler
createBowler(leagueId.getText().toString(), inputBowlerName.getText().toString());
}
}
});
}
}
onNotifyDatasetChanged(List<Bowler>)
方法而不是股票onNotifyDatabsetChanged()
public class BowlerAdapter extends RecyclerView.Adapter<BowlerAdapter.MyViewHolder> {
private Context context;
private List<Bowler> bowlersList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView bowlerLeagueId;
public TextView name;
public TextView timestamp;
public MyViewHolder(View view) {
super(view);
bowlerLeagueId = view.findViewById(R.id.tvLeagueId);
name = view.findViewById(R.id.tvBowlerName);
timestamp = view.findViewById(R.id.timestamp);
}
}
public BowlerAdapter(Context context, List<Bowler> bowlersList) {
this.context = context;
this.bowlersList = bowlersList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int fakeid = android.R.layout.simple_list_item_1;
int realid = R.layout.listview_boweler;
View itemView = LayoutInflater.from(parent.getContext())
.inflate(realid, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Bowler bowler = bowlersList.get(position);
holder.bowlerLeagueId.setText(bowler.getLeagueId());
holder.name.setText(bowler.getName());
//Formatting And Displaying Timestamp
holder.timestamp.setText(formatDate(bowler.getTimestamp()));
}
@Override
public int getItemCount() {
return bowlersList.size();
}
//<<<<<<<<<< Added >>>>>>>>>>
// This will get the actual bowler from the list
public Bowler getItemAtPosition(int position) {
return bowlersList.get(position);
}
//Formatting TimeStamp to 'EEE MMM dd yyyy (HH:mm:ss)'
//Input : 2018-05-23 9:59:01
//Output : Wed May 23 2018 (9:59:01)
private String formatDate(String dateStr) {
try {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = fmt.parse(dateStr);
SimpleDateFormat fmtOut = new SimpleDateFormat("EEE MMM dd yyyy (HH:mm:ss)");
return fmtOut.format(date);
} catch (ParseException e) {
}
return "";
}
public void notifyDatasetChanged(List<Bowler> newbowlerlist) {
bowlersList.clear();
bowlersList.addAll(newbowlerlist);
super.notifyDataSetChanged();
}
}
注意notifyDatasetChanged(List<Bowler)
方法,这会获取更改后的投球手列表并重建与其配合使用的适配器的副本,然后调用适配器的 notfiydatasetChanged
方法。
已添加但未使用的是 getItemAtPosition
可用于在给定位置从适配器返回投球手的方法(这可用于避免更改 Activity 的投球手列表副本)。
这仅包括一些更改,这些更改记录了一些信息,但其他方面没有变化(尽管添加了一些缺失的代码)。
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "leagueapp.db";
public static final int DBVERSION = 1;
SQLiteDatabase mDB;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(Bowler.CRTSQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long insertBowler(String leagueId, String bowlerName) {
//Get Writable Database That We Want To Write Data Too
SQLiteDatabase db = this.getWritableDatabase();
Log.d("INSERTBOWLER","Number of bowlers in db = " + String.valueOf(DatabaseUtils.queryNumEntries(db,Bowler.TABLE_NAME)));
ContentValues values = new ContentValues();
//`id` and `timestamp` Will Be Inserted Automatically
values.put(Bowler.COLUMN_LEAGUE_ID, leagueId);
values.put(Bowler.COLUMN_NAME, bowlerName);
//Insert Row
long id = db.insertOrThrow( Bowler.TABLE_NAME, null, values );
//Close Database Connection
db.close();
//Return Newly Inserted Row Id
return id;
}
public Bowler getBowler(String leagueId) {
//Get Readable Database If We Are Not Inserting Anything
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(Bowler.TABLE_NAME,
new String[]{Bowler.COLUMN_ID, Bowler.COLUMN_LEAGUE_ID, Bowler.COLUMN_NAME, Bowler.COLUMN_TIMESTAMP},
Bowler.COLUMN_LEAGUE_ID + "=?",
new String[]{String.valueOf(leagueId)}, null, null, null, null);
if (cursor.moveToFirst()) {
//Prepare Bowler Object
Bowler bowler = new Bowler(
cursor.getLong(cursor.getColumnIndex(Bowler.COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_NAME)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));
//Close Database Connection
cursor.close();
return bowler;
} else {return null;}
}
public List<Bowler> getAllBowlers(String leagueId) {
List<Bowler> bowlers = new ArrayList<>();
//Select All Query
String selectQuery = "SELECT * FROM " + Bowler.TABLE_NAME + " WHERE " + Bowler.COLUMN_LEAGUE_ID + " = '" + leagueId + "'" + " ORDER BY " +
Bowler.COLUMN_TIMESTAMP + " DESC";
Log.d("GETALLBOWLERS-SQL","SQL used = >>>>" +selectQuery + "<<<<");
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
Log.d("GETALLBOWLERS-CNT","Number of rows retrieved = " + String.valueOf(cursor.getCount()));
//Looping Through All Rows And Adding To The List
if (cursor.moveToFirst()) {
do {
Bowler bowler = new Bowler();
bowler.setId(cursor.getInt(cursor.getColumnIndex(Bowler.COLUMN_ID)));
bowler.setLeagueId(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)));
bowler.setName(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_NAME)));
bowler.setTimestamp(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));
bowlers.add(bowler);
} while (cursor.moveToNext());
}
cursor.close();
//Close Database Connection
db.close();
Log.d("GETALLBOWLERS-CNT","Number of elements in bowlerslist = " + String.valueOf(bowlers.size()));
//Return Bowlers List
return bowlers;
}
public int getBowlersCount() {
String countQuery = "SELECT * FROM " + Bowler.TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
//Return The Count
return count;
}
public int updateBowler(Bowler bowler) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Bowler.COLUMN_LEAGUE_ID, bowler.getLeagueId());
values.put(Bowler.COLUMN_NAME, bowler.getName());
//Updating Row
return db.update(Bowler.TABLE_NAME, values, Bowler.COLUMN_ID + " = ?",
new String[]{String.valueOf(bowler.getId())});
}
public void deleteBowler(Bowler bowler) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete( Bowler.TABLE_NAME, Bowler.COLUMN_ID + " = ?",
new String[]{String.valueOf( bowler.getId())});
db.close();
}
public int deleteBowlerChecked(Bowler bowler) {
SQLiteDatabase db = this.getWritableDatabase();
Log.d("DELETEBOWLER","Attempting to DELETE bowler " + bowler.getName());
int rv = db.delete(Bowler.TABLE_NAME,Bowler.COLUMN_ID + "=?",
new String[]{String.valueOf(bowler.getId())});
if (rv < 1) {
Log.d("DELETEBOWLER", "Bowler with an id of " + String.valueOf(bowler.getId()) + " was not deleted, as it didn't exist.");
}
return rv;
}
}
此wad已添加,它可能与您的相同,也可能不同。
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private BowlerActivity.ClickListener clicklistener;
private GestureDetector gestureDetector;
public RecyclerTouchListener(Context context, final RecyclerView recycleView, final BowlerActivity.ClickListener clicklistener){
this.clicklistener=clicklistener;
gestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child=recycleView.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null){
clicklistener.onLongClick(child,recycleView.getChildAdapterPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child=rv.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null && gestureDetector.onTouchEvent(e)){
clicklistener.onClick(child,rv.getChildAdapterPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
初始屏幕(空数据库):-
点击添加投球手按钮:-
进入Bowler B1并点击“保存”:-
添加了更多投球手:-
Bowler B5 更新:-
保龄球手 B1 和 B6 已删除:-
关于java - 添加新记录时 ListView 不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50724249/
我想知道有没有可能做 new PrintWriter(new BufferedWriter(new PrintWriter(s.getOutputStream, true))) 在 Java 中,s
我正在尝试使用 ConcurrentHashMap 初始化 ConcurrentHashMap private final ConcurrentHashMap > myMulitiConcurrent
我只是想知道两个不同的新对象初始化器之间是否有任何区别,还是仅仅是语法糖。 因此: Dim _StreamReader as New Streamreader(mystream) 与以下内容不同: D
在 C++ 中,以下两种动态对象创建之间的确切区别是什么: A* pA = new A; A* pA = new A(); 我做了一些测试,但似乎在这两种情况下,都调用了默认构造函数,并且只调用了它。
我已经阅读了其他帖子,但它们没有解决我的问题。环境为VB 2008(2.0 Framework)下面的代码在 xslt.Load 行导致 XSLT 编译错误下面是错误的输出。我将 XSLT 作为字符串
我想知道为什么alert(new Boolean(false))打印 false 而不是打印对象,因为 new Boolean 应该返回对象。如果我使用 console.log(new Boolean
本文实例讲述了Python装饰器用法。分享给大家供大家参考,具体如下: 写装饰器 装饰器只不过是一种函数,接收被装饰的可调用对象作为它的唯一参数,然后返回一个可调用对象(就像前面的简单例子) 注
我可以编写 YAML header 来使用 knit 为 R Markdown 文件生成多种输出格式吗?我无法重现 the original question with this title 的答案中
我可以编写一个YAML标头以使用knitr为R Markdown文件生成多种输出格式吗?我无法重现the original question with this title答案中描述的功能。 这个降价
我正在使用vars package可视化脉冲响应。示例: library(vars) Canada % names ir % `$`(irf) %>% `[[`(variables[e])) %>%
我有一个容器类,它有一个通用参数,该参数被限制到某个基类。提供给泛型的类型是基类约束的子类。子类使用方法隐藏(新)来更改基类方法的行为(不,我不能将其设为虚拟,因为它不是我的代码)。我的问题是"new
Java 在提示! cannot find symbol symbol : constructor Bar() location: class Bar JPanel panel =
在我的应用程序中,一个新的 Activity 从触摸按钮(而不是点击)开始,而且我没有抬起手指并希望在新的 Activity 中跟踪触摸的 Action 。第二个 Activity 中的触摸监听器不响
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,
和我的last question ,我的程序无法检测到一个短语并将其与第一行以外的任何行匹配。但是,我已经解决并回答了。但现在我需要一个新的 def函数,它删除某个(给定 refName )联系人及其
这个问题在这里已经有了答案: Horizontal list items (7 个答案) 关闭 9 年前。
我想创建一个新的 float 类型,大小为 128 位,指数为 4 字节(32 位),小数为 12 字节(96 位),我该怎么做输入 C++,我将能够在其中进行输入、输出、+、-、*、/操作。 [我正
我在放置引用计数指针的实例时遇到问题 类到我的数组类中。使用调试器,似乎永远不会调用构造函数(这会扰乱引用计数并导致行中出现段错误)! 我的 push_back 函数是: void push_back
我在我们的代码库中发现了经典的新建/删除不匹配错误,如下所示: char *foo = new char[10]; // do something delete foo; // instead of
A *a = new A(); 这是创建一个指针还是一个对象? 我是一个 c++ 初学者,所以我想了解这个区别。 最佳答案 两者:您创建了一个新的 A 实例(一个对象),并创建了一个指向它的名为 a
我是一名优秀的程序员,十分优秀!