Access and edit child view of custom adapter - java

I have a ListView populated by a custom ArrayAdapter.
The structure of each row is composed by
ImageView
TextView
NumberPicker
ImageButton
Clicking on the ImageButton should show a popup window which contains a color slider and a "ACCEPT" button.
Here is an image that should clarify the layout.
What I would like to do is : by clicking the "ACCEPT" button contained in the popup window, I should retrieve the selected color, set it as background color of the ImageButton and dismiss the popupwindow.
Here is the code :
public View getView(final int position, View convertView, ViewGroup parent) {
_row_view = convertView;
db = new SofosDbDAO(this._ctx);
if(_row_view==null){
// 1. Create inflater
_inflater = (LayoutInflater) _ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
_row_view = _inflater.inflate(R.layout.riga_app,parent,false);
}
// 2. Inflate xml layout
_row_view = _inflater.inflate(R.layout.riga_app, parent, false);
// 3. Initialize child views
_iconaapp = (ImageView)_row_view.findViewById(R.id.riga_app_iv);
_nomeapp = (TextView)_row_view.findViewById(R.id.riga_app_tv);
_numerovibrazioni = (NumberPicker)_row_view.findViewById(R.id.riga_app_np);
_colorenotifica = (ImageButton)_row_view.findViewById(R.id.riga_app_ib);
// 4. Set Values
int iconid = _ctx.getResources().getIdentifier(_sofosapps.get(position).get_app_icon(), "drawable", _ctx.getPackageName());
Drawable icon = _ctx.getResources().getDrawable(iconid);
_iconaapp.setImageDrawable(icon);
String appname = _sofosapps.get(position).get_app_name();
_nomeapp.setText(appname);
_numerovibrazioni.setMinValue(0);
_numerovibrazioni.setMaxValue(5);
_numerovibrazioni.setValue(_sofosapps.get(position).get_vibrations());
//Update DB when number picker value gets changed
_numerovibrazioni.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
SofosApp app = _sofosapps.get(position);
app.set_vibrations(newVal);
db.openDb();
db.updateAppVibrations(app);
db.closeDb();
Log.d("DEBUG", "Updated nr of vibrations");
}
});
//Set initial ImageButton background color
_colorenotifica.setBackgroundColor(_sofosapps.get(position).get_color());
//Show popup window on click of ImageButton
_colorenotifica.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
_popupcontainer = (ViewGroup)_inflater.inflate(R.layout.color_picker_popup,null);
_puw = new PopupWindow(_popupcontainer,800,600,true);//view,dimensioni e focusable
_btn_applica = (Button) _popupcontainer.findViewById(R.id.color_picker_btn_applica);
_tv_applica_colore = (TextView) _popupcontainer.findViewById(R.id.color_picker_tv);
_tv_applica_colore.setText(_sofosapps.get(position).get_app_name());
_lss = (LobsterShadeSlider)_popupcontainer.findViewById(R.id.color_picker_ls);
_puw.showAtLocation(_popupcontainer, Gravity.CENTER, 20, 50);
Log.d("DEBUG","I clicked on imagebutton and opened my popupwindow");
}
});
//**********************************************************
*********************** CRUCIAL POINT **********************
************************************************************
//Click of accept button inside popupwindow
_btn_applica.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newcolor = _lss.getColor();
String dbg = "color = " + String.valueOf(newcolor);
Log.d("DEBUG", dbg);
_colorenotifica.setBackgroundColor(newcolor);
_puw.dismiss();
_colorenotifica.invalidate();
Log.d("DEBUG", "Cliked accept");
}
});
// 5. retrn rowView
return _row_view;
}
I realize that this approach is not correct as the background image of the imagebutton does not change. Also , for some reason, I fail to create a new popup window for each row : when I click on any image button , the same popup window appears with the textview text set to "Twitter" , the last row.
What is the right way of doing this?
Thank you for the help!

You should change value of color in your array _sofosapps and then call notifydatasetchanged on adapter.
_colorenotifica.setTag(position);
_colorenotifica.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = (int)v.getTag();
_popupcontainer = (ViewGroup)_inflater.inflate(R.layout.color_picker_popup,null);
_puw = new PopupWindow(_popupcontainer,800,600,true);//view,dimensioni e focusable
_btn_applica = (Button) _popupcontainer.findViewById(R.id.color_picker_btn_applica);
_tv_applica_colore = (TextView) _popupcontainer.findViewById(R.id.color_picker_tv);
_tv_applica_colore.setText(_sofosapps.get(position).get_app_name());
_lss = (LobsterShadeSlider)_popupcontainer.findViewById(R.id.color_picker_ls);
_puw.showAtLocation(_popupcontainer, Gravity.CENTER, 20, 50);
_btn_applica.setTag(position);
Log.d("DEBUG","I clicked on imagebutton and opened my popupwindow");
}
});
_btn_applica.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newcolor = _lss.getColor();
String dbg = "color = " + String.valueOf(newcolor);
Log.d("DEBUG", dbg);
int position = (int)v.getTag();
_sofosapps.get(position).setColor(dbg);
notifyDataSetChanged();
_puw.dismiss();
}
});

invoke custom dialog on onClick event of _colorenotifica and listen to it's button click events, then get the appropriate item object based on position and apply changes...
.
.
_colorenotifica.setOnClickListener(new View.OnClickListener() {
int mPosition = position;
#Override
public void onClick(View v) {
/**
* invoke custom dialog, add button..
*/
dlg.setButton(AlertDialog.BUTTON_POSITIVE, "Accept", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
getItem(mPosition); // apply changes to the item at position `mPosition`
}
});
}
});
.
.

Related

How to remove added views programmatically

I have a dialog wherein a user can add EditText and also remove it. I have successfully added EditText programmatically but my code for removing it doesn't work. I'm following this tutorial but in my case setup is inside a dialog.
and also i want to get all the the texts on those EditTexts and store it inside an Array.
This is my code:
public void showSurveyDialog(Context context) {
ImageButton btnAddChoices, btnRemoveChoice;
Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.survey_content);
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
btnAddChoices = dialog.findViewById(R.id.btn_add_choices);
LinearLayout choiceLayout = dialog.findViewById(R.id.choice_layout);
btnAddChoices.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = dialog.getLayoutInflater().inflate(R.layout.choice_item, null);
// Add the new row before the add field button.
choiceLayout.addView(rowView, choiceLayout.getChildCount() - 1);
ImageButton imageButton = dialog.findViewById(R.id.btn_choice_close);
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("asdass","ASDASd");
choiceLayout.removeView((View)v.getParent());
}
});
}
});
dialog.show();
}
When pressing btnAddChoices a layout with EditText and Button(for removing) is automatically added to a linear layout. I'am trying to make the remove button to work but it doesn't remove the view.
you can try my add and remove code for references, this can add or remove view programmatically:
private void addressField(View view){
final int[] textCount = {0};
LinearLayout addressLayout = view.findViewById(R.id.address_layout);
addressScroll.removeView(addressLayout);
View layout2 = LayoutInflater.from(view.getContext()).inflate(R.layout.address_text_field
, addressLayout,false);
layout2.setTag("address"+Integer.toString(counter));
addressLayout.addView(layout2);
addressScroll.addView(addressLayout);
ImageView deleteButton = layout2.findViewWithTag("address"+Integer.toString(counter))
.findViewById(R.id.delete_address);
TextFieldBoxes addressText = layout2.findViewWithTag("address"+Integer.toString(counter))
.findViewById(R.id.address_wrapper);
addressText.setSimpleTextChangeWatcher((theNewText, isError) -> {
if(Objects.equals(theNewText, "")){
textCount[0] = 0;
addressLayout.removeView(layout2);
}
if(theNewText.length() == 1 && textCount[0] == 0){
addressField(view);
ExtendedEditText addressText2 = layout2.findViewWithTag("address"+Integer.toString(counter-1))
.findViewById(R.id.address_text);
addressText2.requestFocus();
counter++;
}
textCount[0]++;
});
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addressLayout.removeView(layout2);
}
});
}
hope can solve your problems

onItemClick ListView Listener not entering the first time

I have a problem in the onCreateView method, I have a fragment which has a button named: variablesButton, every time I click on it, it creates an AlertDialog in which I use the setMultiChoiceItems to display certain items. I'm trying to create a Select all in the first index to select all the items in the Dialog or to deselect them.
When I click the first time it does not work, but after clicking on it the second time it works (entering finally the onItemClick method). I already tried setFocusable to the listview, also FOCUS_BLOCK_DESCENDANTS, but it won't enter the first time I click, how can I solve this?.
variablesButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AlertDialog.Builder mBuilder = new AlertDialog.Builder(getContext());
mBuilder.setTitle("Sensors");
mBuilder.setCancelable(false);
mBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
listSensors.clear();
for (int a=0; a<checkedItems.length; a++) {
if (checkedItems[a])
listSensors.add(sensorNames[a]);
}
}
});
mBuilder.setMultiChoiceItems(sensorNames, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checkedItems[which] = isChecked;
Log.i("checked", String.valueOf(which));
final ListView listView = ((AlertDialog) dialog).getListView();
listView.setFocusable(false);
listView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
boolean isChecked = listView.isItemChecked(pos);
Log.i("pos", String.valueOf(pos));
if (pos == 0) {
for (int i = 1; i < checkedItems.length; i++) { // we start with first element after "Select all" choice
if (isChecked && !listView.isItemChecked(i) || !isChecked && listView.isItemChecked(i)) {
listView.performItemClick(listView, i, 0);
}
}
}
}
});
}
});
mBuilder.create();
mBuilder.show();
}
});
Your AdapterView.OnItemClickListener() is inside the variablesButton.setOnClickListener therefore AdapterView listener is set after variablesButton click listener fire once.
Move adapterView listener to the outside of this variable button clicked action. And set AdapterView.OnItemClickListener() while initializing activity or initializing related content.

Get IndexOutOfBoundsException: Index: 1, Size: 1 When Clicking on Row

I had this working in the past, but I made some changes to my code and now, whenever I delete a row from the ListView and click on one of the remaining rows, I am getting IndexOutOfBoundsException: Index: 1, Size: 1.
This only seems to be happening when there is a single row remaining. If there are more than one row remain, this error does not appear.
The image above shows that the when there are more than one row remaining the error does not occur.
I am not sure why this would be happening since none of the code for selecting and deleting a row has changed.
I have checked other posts on this site but none of them seem to be similar to what I am experiencing.
Android IndexOutOfBoundsException: Index: 1, Size: 1
OutOfBoundException index:1, size:1
java jtable removeRow : java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
I have posted my code below.
Logcat:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.get(ArrayList.java:411)
at ca.rvogl.tpbcui.views.LeagueAdapter$2.onClick(LeagueAdapter.java:116)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Code for selecting a row in the listview:
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
League league = leaguesList.get(position);
int id = league.getId();
String leagueId = String.valueOf(id);
holder.id.setText(leagueId);
holder.name.setText(league.getName());
holder.basescore.setText(league.getBaseScore());
holder.basescorepercentage.setText(league.getBaseScorePercentage());
if (league.getAverage() != "") {
holder.leagueAverage.setText(String.format("League Avg: %s", league.getAverage()));
} else {
holder.leagueAverage.setText(String.format("League Avg: %s", "0"));
}
//Formatting And Displaying Timestamp
holder.timestamp.setText(formatDate(league.getTimestamp()));
holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//creating a popup menu
PopupMenu popup = new PopupMenu(context, holder.buttonViewOption);
//inflating menu from xml resource
popup.inflate(R.menu.league_options_menu);
//adding click listener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.profile:
((MainActivity) context).showLeagueDialog(true, leaguesList.get(position), position);
break;
case R.id.delete:
((MainActivity) context).deleteLeague(position);
break;
}
return false;
}
});
//displaying the popup
popup.show();
}
});
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int leagueId = leaguesList.get(position).getId();
Intent myIntent = new Intent(context, BowlerActivity.class);
myIntent.putExtra("leagueId", leagueId);
context.startActivity(myIntent);
}
});
}
Code for deleting a row:
//Deleting League From SQLite Database And Removing The League Item From The List By Its Position
public void deleteLeague(int position) {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Series will be deleted.", Snackbar.LENGTH_LONG)
.setActionTextColor(Color.YELLOW)
.setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
//Deleting The League From The Database
db.deleteLeague(leaguesList.get(position));
//Removing League From The List
leaguesList.remove(position);
mAdapter.notifyItemRemoved(position);
toggleEmptyLeagues();
}
});
snackbar.show();
}
The error seems to be happening with this line int leagueId = leaguesList.get(position).getId();
Any help getting this error fixed would be greatly appreciated.
BowlerActivity.java
public class BowlerActivity extends AppCompatActivity {
private BowlerAdapter mAdapter;
private final List<Bowler> bowlersList = new ArrayList<>();
private TextView noBowlersView;
private DatabaseHelper db;
private TextView leagueId;
private String savedLeagueId;
private TextView seriesleagueId;
private String seriesLeagueId;
private TextView bowlerAverage;
private TextView bowlerHandicap;
private String savedBowlerAverage;
private static final String PREFS_NAME = "prefs";
private static final String PREF_BLUE_THEME = "blue_theme";
private static final String PREF_GREEN_THEME = "green_theme";
private static final String PREF_ORANGE_THEME = "purple_theme";
private static final String PREF_RED_THEME = "red_theme";
private static final String PREF_YELLOW_THEME = "yellow_theme";
#Override protected void onResume() {
super.onResume();
db = new DatabaseHelper( this );
mAdapter.notifyDatasetChanged( db.getAllBowlers( savedLeagueId ) );
}
#Override
protected void onCreate(Bundle savedInstanceState) {
//Use Chosen Theme
SharedPreferences preferences = getSharedPreferences( PREFS_NAME, MODE_PRIVATE );
boolean useBlueTheme = preferences.getBoolean( PREF_BLUE_THEME, false );
if (useBlueTheme) {
setTheme( R.style.AppTheme_Blue_NoActionBar );
}
boolean useGreenTheme = preferences.getBoolean( PREF_GREEN_THEME, false );
if (useGreenTheme) {
setTheme( R.style.AppTheme_Green_NoActionBar );
}
boolean useOrangeTheme = preferences.getBoolean( PREF_ORANGE_THEME, false );
if (useOrangeTheme) {
setTheme( R.style.AppTheme_Orange_NoActionBar );
}
boolean useRedTheme = preferences.getBoolean( PREF_RED_THEME, false );
if (useRedTheme) {
setTheme( R.style.AppTheme_Red_NoActionBar );
}
boolean useYellowTheme = preferences.getBoolean( PREF_YELLOW_THEME, false );
if (useYellowTheme) {
setTheme( R.style.AppTheme_Yellow_NoActionBar );
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bowler);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Objects.requireNonNull( getSupportActionBar() ).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),MainActivity.class));
finish();
overridePendingTransition(0, 0);
}
});
savedLeagueId = String.valueOf(getIntent().getIntExtra("leagueId",2));
leagueId = findViewById(R.id.tvLeagueId);
bowlerAverage = (TextView) findViewById(R.id.tvBowlerAverage);
bowlerHandicap = (TextView) findViewById(R.id.tvBowlerHandicap);
CoordinatorLayout coordinatorLayout = findViewById( R.id.coordinator_layout );
RecyclerView recyclerView = findViewById( R.id.recycler_view );
noBowlersView = findViewById(R.id.empty_bowlers_view);
db = new DatabaseHelper(this);
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();
}
//Inserting New Bowler In The Database And Refreshing The List
private void createBowler(String leagueId, String bowlerName) {
String bowlerAverage = "0";
//Inserting Bowler In The Database And Getting Newly Inserted Bowler Id
long id = db.insertBowler(leagueId, bowlerName, bowlerAverage);
//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(db.getAllBowlers(savedLeagueId));
//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
public void deleteBowler(int position) {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Series will be deleted.", Snackbar.LENGTH_LONG)
.setActionTextColor(Color.YELLOW)
.setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
//Deleting The Bowler From The Database
db.deleteBowler(bowlersList.get(position));
//Removing The Bowler From The List
bowlersList.remove(position);
mAdapter.notifyItemRemoved(position);
db.leagueAverageScore(savedLeagueId);
toggleEmptyBowlers();
}
});
snackbar.show();
}
//Opens Dialog With Edit/Delete Options
private void showActionsDialog(final int position) {
LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
View view = View.inflate(this, R.layout.dialog_options_1, null);
final AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(new ContextThemeWrapper(BowlerActivity.this, R.style.AppTheme));
alertDialogBuilderUserInput.setView(view);
alertDialogBuilderUserInput.setCancelable(true);
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
//Cancel
final ImageButton cancel_btn = (ImageButton) view.findViewById(R.id.cancel);
cancel_btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
alertDialog.cancel();
}
});
//Edit
ImageButton edit_btn = (ImageButton) view.findViewById(R.id.edit);
edit_btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
showBowlerDialog(true, bowlersList.get(position), position);
alertDialog.dismiss();
}
});
ImageButton delete_btn = (ImageButton) view.findViewById(R.id.delete);
delete_btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Bowler will be deleted.", Snackbar.LENGTH_LONG)
.setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteBowler(position);
}
});
snackbar.show();
alertDialog.dismiss();
}
});
Window window = alertDialog.getWindow();
window.setGravity(Gravity.TOP);
alertDialog.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
public void showBowlerDialog(final boolean shouldUpdate, final Bowler bowler, final int position) {
LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
final View view = View.inflate(this, R.layout.dialog_bowler, null);
AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(new ContextThemeWrapper(BowlerActivity.this, R.style.AppTheme));
alertDialogBuilderUserInput.setView(view);
alertDialogBuilderUserInput.setCancelable(true);
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();
}
});
ImageView bowlerName = (ImageView) view.findViewById (R.id.ivBowlerName);
bowlerName.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AlertDialog.Builder bowlerName = new AlertDialog.Builder(BowlerActivity.this);
bowlerName.setMessage("Enter the name of the bowler to hold your new scores.");
bowlerName.setCancelable(true);
bowlerName.create();
bowlerName.show();
}
});
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())) {
Snackbar.make( view, "Enter Bowler Name", Snackbar.LENGTH_LONG )
.setAction( "Action", null ).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 void onRestart() {
super.onRestart();
//When BACK BUTTON is pressed, the activity on the stack is restarted
//Do what you want on the refresh procedure here
}
#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) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
overridePendingTransition(0, 0);
return true;
}
return super.onOptionsItemSelected( item );
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
//Check If Request Code Is The Same As What Is Passed - Here It Is 1
if(requestCode==1)
{
String savedLeagueId=data.getStringExtra("seriesLeagueId");
String seriesBowlerId=data.getStringExtra("seriesBowlerId");
bowlersList.addAll(db.getAllBowlers(savedLeagueId));
}
}
#Override
public void onBackPressed() {
startActivity(new Intent(getApplicationContext(),MainActivity.class));
finish();
overridePendingTransition(0, 0);
}
}
This is the line that it is complaining about. This worked perfectly before I move the onClick() to the adapter.
savedLeagueId = String.valueOf(getIntent().getIntExtra("leagueId",2));
I am really hoping that someone can help me get this issue resolved. I have tried several different approaches from other stackoverflow posts and I am still not able to resolve it.
mAdapter.notifyItemRemoved(position);
Means that the adapter will shift and animate items up. However, the items will not be redrawn.
You can observe that by clicking on the last item of your list after deleting any item: you should see the same crash.
And by clicking on any item after the one you deleted (except the last one), the details view should show the next item instead of the one you clicked.
The issue is that position is no longer relevant, because the indices have changed. Instead use the value for leagueId that you already have in your binder. Simply remove the int leagueId that is shadowing the String leagueId and that should work as expected.
The problem is that the view was already bind and the position at this method:
holder.name.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int leagueId = leaguesList.get(position).getId(); // here position will still be 1 after deletion
//...
}
});
belongs to the old index. To fix it, use the same object you fot previously.
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int leagueId = league.getId(); //league object will be the same
//...
}
});
****Try This****
#Override
protected void onBindViewHolder(#NonNull final BoardsViewHolder holder, final int position, #NonNull final Board model) {
holder.setTitle(model.getBoardTitle());
holder.setDesc(model.getBoardDesc());
holder.setDate(model.getCreatedOn());
holder.mDeleteBoardButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
alert.setTitle("Delete Board");
alert.setMessage("This Board will be deleted forever");
alert.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
final ProgressDialog loading = new ProgressDialog(mContext);
loading.setMessage("Deleting...");
loading.show();
getSnapshots().getSnapshot(position).getReference().delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
notifyDataSetChanged();
loading.dismiss();
}else {
loading.dismiss();
Toast.makeText(mContext,"Something went wrong please try again later",Toast.LENGTH_LONG).show();
}
}
});
}
});
alert.setNegativeButton("Keep", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert.show();
}
});
This is the problem of zero based elements. Your code is trying to access an non existing element index. Launch your app in debug mode and line by line see what is happening. Android studio has an excellent debugger built-in, so it is very easy to go step by step and see what is happening with your variables.

How to move between the elements of recyclerview inside its adapters

I couldn't phrase the question perfectly with my problem, but basically what I want to achieve is this:-
I have recyclerview of items that contains textview for example, when the item is clicked; a custom dialog will show containing the same content of the clicked element.
so far so good, in the same dialog there's two arrow (left & right) at each of its sides, the arrows buttons should navigate between the recyclerview items and update the content according to the new position.
Here's what I did:
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.tvTitle.setText(data.get(position).getTitle());
holder.itemView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
//Initializing the custom dailog
final Dialog dialog = new Dialog(context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow() .setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.getWindow().getAttributes().gravity = Gravity.TOP;
dialog.setContentView(R.layout.dailog);
dialog.show();
ImageView RightArrow = (ImageView) dialog.findViewById(R.id.dia_right_arrow);
ImageView LeftArrow = (ImageView) dialog.findViewById(R.id.dia_left_arrow);
final TextView textViewTitle = (TextView) dialog.findViewById(R.id.dia_tvTtile);
textViewTitle.setText(data.get(position).getTitle());
RightArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int curPosi = 0;
if (data.size() != 0) {
curPosi = position+1;
}
textViewTitle.setText(data.get(position).getTitle());
}
});
LeftArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int curPosi = 0;
if (data.size() != 0) {
curPosi = position-1;
}
textViewTitle.setText(data.get(position).getTitle());
} });
}});
}
The Result:
When I click on the right arrow it works 100% , but if I click again nothing happens !!
And If click the left arrow at anytime it gives crash with this exception:
java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
Is it possible to achieve a loop effect, what I mean is when I reach
the last index and the click again it shows the first index and vice
versa..!
Any help?
It seems the issue is from how you check your click limits. You can try this
Add curPosi as a class member variable
private int curPosi;
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.tvTitle.setText(data.get(position).getTitle());
holder.itemView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
curPosi = position
//Initializing the custom dailog
final Dialog dialog = new Dialog(context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow() .setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.getWindow().getAttributes().gravity = Gravity.TOP;
dialog.setContentView(R.layout.dailog);
dialog.show();
ImageView RightArrow = (ImageView) dialog.findViewById(R.id.dia_right_arrow);
ImageView LeftArrow = (ImageView) dialog.findViewById(R.id.dia_left_arrow);
final TextView textViewTitle = (TextView) dialog.findViewById(R.id.dia_tvTtile);
textViewTitle.setText(data.get(position).getTitle());
RightArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int lastIndex = data.size()-1;
if (lastIndex == curPosi ) { // this prevents the crash, so if the next button is clicked while the last index is showing it will reset and show the first one..!
curPosi = 0;
} else if(curPosi < data.size()) {
curPosi++;
}
textViewTitle.setText(data.get(curPosi).getTitle());
}
});
LeftArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//same thing here with this "if", when the previous button clicked from the first; it will show the last item..!
if (curPosi == 0) {
curPosi = data.size();
}
if (curPosi > 0) {
curPosi--;
}
textViewTitle.setText(data.get(curPosi).getTitle());
} });
}});
}

onclicklistener on the specific item of the recyclerview in android

I am going to ask very basic question, but i am stuck in it for a long time.
after card view there is an recycleview which has 2 images in each row.
now i want to create the click listener on the images rather than the recycleview.
the corresponding layout(layout_main.xml) of this activity(MainActivity.java) contain only recyclerview. the elements of each row is in another layout(layout_images.xml). i am getting the images from layout_images.xml and inflate them in the adapter class(Adapter.java).
now how to put action listener on the images only.
secondly, i want to get the image on which i clicked. how to get that.
like, when we click on a view we create some method as
public void onClick(View view){
// some code here
}
where view is the object on which we clicked. in my case how to get the image on which i clicked.
using type cast it might be throw an exception when user doesnot click on image.
Multiple onClick events inside a recyclerView:
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public ImageView iconImageView;
public TextView iconTextView;
public MyViewHolder(final View itemView) {
super(itemView);
iconImageView = (ImageView) itemView.findViewById(R.id.myRecyclerImageView);
iconTextView = (TextView) itemView.findViewById(R.id.myRecyclerTextView);
// set click event
itemView.setOnClickListener(this);
iconTextView.setOnClickListener(this);
// set long click event
iconImageView.setOnLongClickListener(this);
}
// onClick Listener for view
#Override
public void onClick(View v) {
if (v.getId() == iconTextView.getId()) {
Toast.makeText(v.getContext(), "ITEM PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(v.getContext(), "ROW PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
}
}
//onLongClickListener for view
#Override
public boolean onLongClick(View v) {
final AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setTitle("Hello Dialog")
.setMessage("LONG CLICK DIALOG WINDOW FOR ICON " + String.valueOf(getAdapterPosition()))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
return true;
}
}
To get which item was clicked you match the view id i.e. v.getId() == yourViewItem.getId()
You have to set onClickListener to the ImageViews inside the onBindViewHolder method, refer the following LOCs for reference(code to be inside onBindViewHolder method)
holder.imageView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//put your code for first imageview here
}
});
holder.imageView2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//put your code for second imageView here
}
});
In Recycle View Holder, Write your onclick listener code inside
#Override
public void onBindViewHolder(CardHolder holder, final int position) {
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//TODO
}
}
}
implement the View.OnClickListener in your ViewHolder class and implement the onClick method. Then set the click listener for your ImageView to this click listener. Add the required functionality in the onClick method. If you want to implement the click functionality in other class simply create an interface and declare a click method in it. You can implement this method in the activity/fragment that contains this RecycleView. Then from your view holders onClick method you can invoke the interface method.
You can check with tag or it of element like this:
public void onClick(View view){
if(view.getId() == image1.getId())
{
}else if(view.getId() == image2.getId())
{}
}
First of all set onclickListener to each view you want to be clicked. Good place to do it in viewHolderConstructor. eg
public class GalleryManyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.im_img) RoundedCornersImageView imImg;
#BindView(R.id.tv_title) MyTextView tvTitle;
#BindView(R.id.tv_label) MyTextView tvLabel;
#BindView(R.id.tv_date) MyTextView tvDate;
#BindView(R.id.im_gallery_one) RoundedCornersImageView imGalleryOne;
#BindView(R.id.im_gallery_two) RoundedCornersImageView imGalleryTwo;
#BindView(R.id.im_gallery_three) RoundedCornersImageView imGalleryThree;
#BindView(R.id.im_gallery_four) RoundedCornersImageView imGalleryFour;
#BindView(R.id.tv_more) MyTextView tvMore;
#BindView(R.id.root) RelativeLayout root;
public GalleryManyViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
view.setOnClickListener(onClickListener);
imGalleryOne.setOnClickListener(onClickListener);
imGalleryTwo.setOnClickListener(onClickListener);
imGalleryThree.setOnClickListener(onClickListener);
imGalleryFour.setOnClickListener(onClickListener);
view.setTag(this);
}
Generally you do not need to make anything specific with those view, like setting tags (Also some usefull libraries like Glied, which sets its own tags to imageviews will malfunction if you set you own tag. In on clickListener find adapter position of the view to be able to retrive the corresponding data
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override public void onClick(View v) {
View view = v;
View parent = (View) v.getParent();
while (!(parent instanceof RecyclerView)){
view=parent;
parent = (View) parent.getParent();
}
int position = recyclerView.getChildAdapterPosition(view);
}
as described here
Then but checking views id, evaluete what you want to do
switch (v.getId()) {
case R.id.im_gallery_one: {
p = 0;
}
break;
case R.id.im_gallery_two: {
p = 1;
}
break;
case R.id.im_gallery_three: {
p = 2;
}
break;
case R.id.im_gallery_four: {
p = 3;
}
break;
}

Categories

Resources