When I remove some item in RecyclerView, but it comes to a bug, the bug is hard to occur,but it will occur sometimes. Sometimes the item is not deleted, and still show in recyclerView and can not remove forever. Below is my code:
//the positions is a collection,which collect my item positions that should be removed.
int realPosition;
int temp = 0;
for (int i = 0; i < positions.size(); i++) {
realPosition = positions.get(i) - temp;
getAdapter().remove(realPosition);
getAdapter().notifyItemRemoved(realPosition);
temp++;
}
and my English is poor, hope you can understand. Can anyone help me? Thank you very much.
If you want to remove items from recycler view with in loop then try this
int realPosition;
int temp = 0;
for (int i = 0; i < positions.size(); i++) {
realPosition = positions.get(i) - temp;
getAdapter().remove(realPosition);
temp++;
}
getAdapter().notifyDataSetChanged();
The problem with your code is that each time your loop runs recyclerView's positions get updated so your notifyItemRemoved(realPosition) is removing something other than what you actually want....Hope this helps
Related
I try to make components to be invisible but after I clicked a button. My app stop immediately
I have an array like this
I try to make components to disappear like this
Your loop is going out of bounds because your array has 6 elements in it and you're iterating from 0 to 6 (that's seven iterations)
Replace:
for (int i = 0; i < 7; i++) {
findViewById(groupSong2[i]).setVisibility(View.INVISIBLE)
}
With this:
for (int i = 0; i < 6; i++) {
findViewById(groupSong2[i]).setVisibility(View.INVISIBLE)
}
Or even better:
for (int i = 0; i < groupSong2.length; i++) {
findViewById(groupSong2[i]).setVisibility(View.INVISIBLE)
}
I have a 4x4 tile of letters. I wanted to have a validation that only those letters nearest to the tapped/clicked/pressed letter must be clickable and others are set as unclickable. I have my code (see below) for image1. I am having a second thought of how will I enable disabled ImageButton when I tap ImageButton near it.
Example of set:
1 | 5 | 9 | 13
2 | 6 | 10 | 14
3 | 7 | 11 | 15
4 | 8 | 12 | 16
If I clicked/pressed 1 then the 2, 5 and 6 are clickable and the rest are not. Then, I'll click 2 and 1, 3, 5, 6 and 7 must be clickable.
QUESTIONS:
How can I avoid button being clicked again if its already clicked?
How can I enable disabled button and avoiding my Q1?
I am using Android Studio.
Code
if (image1.isPressed()) {
image1.setClickable(false);
image2.setClickable(true);
image3.setClickable(false);
image4.setClickable(false);
image5.setClickable(true);
image6.setClickable(true);
image7.setClickable(false);
image8.setClickable(false);
image9.setClickable(false);
image10.setClickable(false);
image11.setClickable(false);
image12.setClickable(false);
image13.setClickable(false);
image14.setClickable(false);
image15.setClickable(false);
image16.setClickable(false);
}
TIA :)
Avoid writing conditional code. Writing if for each and every image click is a bad practice. So, you can create an arraylist which will always hold the clickable buttons. Based on the clicked button, change this arraylist. Pass this list to a method, which shall enable or disable the clicks for you.
This isn't really about ImageButtons, but rather, what algorithm or methodology would you use to determine which regions are clickable, based on the current state of the system.
We need to separate the logic somewhat. On one side you have your View. Let's just put everything related to updating your grid into a black box, say void updateGrid(List<List< Boolean>> grid). Let's maintain a matrix with entries determining whether or not a button is clickable.
Initially all of the buttons are clickable. You're going to get some notification when a button is clicked, say from a callback void onButtonClick(int i, int j), where i and j give the position of the button. I'm deliberately being vague about this, you'll most likely get an id, and need to resolve the i and j positions yourself. In which case perhaps you'll want to encapsulate the buttonStates and positions in some kind of object - it's up to you.
private <List<List<Boolean>> mGrid;
private static final int GRID_LENGTH = ...;
private static final int GRID_WIDTH = ...;
private static final defaultValue = false;
public void onButtonClick(int i, int j) {
List<List<Boolean>> newGrid = selectGridRegion(i, j);
updateGrid(newGrid);
}
private List<List<Boolean>> selectGridRegion(int i, int j) {
if (!isValidRegion(i, j)) {
return mGrid;
}
ArrayList<ArrayList<Boolean>> grid = makeGrid();
for (int row = 0; row < GRID_LENGTH; row++) {
ArrayList<Boolean> gridRow = grid.get(row);
for (int col = 0; col < GRID_WIDTH; col++) {
gridRow.set(col, isNeighboringRegion(i, j, row, col));
}
}
return grid;
}
private static boolean isNeighboringRegion(int i, int j, int m, int n) {
return (Math.abs(i - m) == 1 && Math.abs(j - n) == 1);
}
private static List<List<Boolean>> makeGrid() {
ArrayList<ArrayList<Boolean>> grid = new ArrayList<ArrayList<Boolean>>();
for (int i = 0; i < GRID_LENGTH; i++) {
ArrayList<Boolean> row = new ArrayList<Boolean>();
for (int j = 0; j < GRID_WIDTH; j++) {
row.add(defaultValue);
}
grid.add(row);
}
return grid;
}
private static boolean isValidRegion(int i, int j) {
boolean isValid = false;
if (0 <= i && i < GRID_LENGTH) {
if (0 <= j && j < GRID_WIDTH) {
isValid = true;
}
}
return isValid;
}
Now, that's a general approach to modeling the grid. All these method except for onButtonClick sound very much like they should be encapsulated in a Grid class! You might want to extend ArrayList, or something similar.
I need a counter that when it reaches the maximum value, starts to count from the beginning. I tried some if statements, but i am new in android developing and my attempts was wrong. Please help me a little. Thank you
Example:
int maxValue = 10;
for (int i = 0; i <= maxValue; i++)
{
if ( i == maxValue)
{
i = 0;
}
}
I have programmed a basic gaming App that consists of blocks which can be exchanged by a swipe (similar to CandyCrush). I succeeded in recognizing the swipe gesture but my code that changes the positions of the Views (blocks) within a GridLayout does only work in the emulator but not on a real device (Samsung Galaxy S3).
Also I couldn't find a way of animating the interchange of the two views. I've added android:animateLayoutChanges="true" to the GridLayout XML but it didn't change anything.
Here's my exchanging code:
// change to blocks positions in grid layout
GridLayout.LayoutParams sourceParams = (GridLayout.LayoutParams)this.imageView.getLayoutParams();
GridLayout.LayoutParams targetParams = (GridLayout.LayoutParams)otherBlock.imageView.getLayoutParams();
GridLayout.Spec sourceRowSpec = sourceParams.rowSpec;
GridLayout.Spec sourceColumnSpec = sourceParams.columnSpec;
sourceParams.rowSpec = targetParams.rowSpec;
sourceParams.columnSpec = targetParams.columnSpec;
targetParams.rowSpec = sourceRowSpec;
targetParams.columnSpec = sourceColumnSpec;
this.imageView.setLayoutParams(sourceParams);
otherBlock.imageView.setLayoutParams(targetParams);
gameGridLayout.requestLayout();
And here's a screenshot of the App:
You should have an index table of your layout, and in your drawing method you run through this index to draw each block.
Like that:
private int [][] index;
void onDraw(Canvas canvas) {
for (int i = 0; i < MAX_BLOCK_HEIGHT; i++) {
for (int j = 0; j < MAX_BLOCK_WIDTH; j++) {
// Draw block index[i][j]
}
}
}
void swapBlock(int blockX, int blockY, int relativePos) {
int tmpBlock = index[blockY][blockX];
if (relativePos == AT_LEFT) {
index[blockY][blockX] = index[blockY][blockX - 1];
index[blockY][blockX - 1] = tmpBlock;
}
// And so on...
}
And this index can be helpful all the time, not only for blit.
int[] images2 = {
R.drawable.wrong, R.drawable.reviewp,
R.drawable.bowl, R.drawable.ic_action_search
};
List<int[]> pic=Arrays.asList(images2);
Collections.shuffle(pic);
Random random = new Random();
for(int i = 0 ; i <= 3 ; i++){
ReciverI[i].setBackgroundResource(images2[ "at here i want to get the image position" ]);
}
help me to get the position of image
this is not working
ReciverI[i].setBackgroundResource(images2[Integer.parseInt(pic.get(i).toString())]);
this give me wrong result
I rewrite the code
Solution 1
Integer[] images2 = {R.drawable.wrong, R.drawable.reviewp, R.drawable.bowl,R.drawable.ic_action_search};
List<Integer> pic=Arrays.asList(images2);
Collections.shuffle(pic);
for(int i = 0 ; i <= pic.size() ; i++){
ReciverI[i].setBackgroundResource(pic.get(i))
}
You want absolutely to conserve the primitiv int then you have to make a little walk around
Solution 2
List<Integer> pic = new ArrayList<Integer>();
for (int index = 0; index < images2.length; index++)
{
pic.add(images2[index]);
}
Collections.shuffle(pic);
for(int i = 0 ; i <= pic.size() ; i++){
ReciverI[i].setBackgroundResource(pic.get(i))
}
ReciverI[i].setBackgroundResource(pic.get(i))
Sorry wasn't paying attention. You should just make your List<int> and it will work.
As your snippet is now, it has no use to have a List of integer arrays.