Reputation: 407
I'm working on a slider puzzle Android app, so I'm using a GridView to display 16 images representing tiles. One of the tiles will consist of a plain white image (representing the background). The idea is that if the user clicks on any tile neighboring the white tile, the selected tile and the white tile will switch positions.
I'm trying to implement this by setting the white tile to the tile selected by the user, and vice versa. I saved the position of the white tile (it starts off at position 15) in the variable masterTilePos, and using the ImageAdapter Integer array referring to the images in my R.drawable file, set the image at masterValPos to the image at the selected index, and the selected image to the white tile. However, when I run the program, the tiles only successfully switch the first time: after that, it doesn't work properly and the order of the tiles within the GridView is ruined. I think it may because the array is simply referring to the actual image objects, but I'm not sure how to what to do instead; it has already been three days since I ran into this problem. Here is my code:
//GRID VIEW
public class MainActivity extends ActionBarActivity {
int masterTilePos = 15;
GridView gridview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
//These methods check if a neighboring tile is white, if there is one, swap() is called
if(checkUp(position) || checkDown(position) || checkLeft(position) || checkRight(position)) {
swap(position);
}
}
});
}
public void swap(int pos) {
ImageAdapter updater = new ImageAdapter(this);
//This is where I try to switch the images, and seems to be the source of the problem
int val = updater.mThumbIds[masterTilePos];
updater.mThumbIds[masterTilePos] = updater.mThumbIds[pos];
updater.mThumbIds[pos] = val;
updater.notifyDataSetChanged();
gridview.setAdapter(updater);
gridview.invalidateViews();
masterTilePos = pos;
}
}
//IMAGE ADAPTER
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels / 4;
int height = metrics.heightPixels / 4;
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(width, height));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(1, 1, 1, 1);
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// the array containing references to the images
public Integer[] mThumbIds = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7,
R.drawable.pic8,
R.drawable.pic9,
R.drawable.pic10,
R.drawable.pic11,
R.drawable.pic12,
R.drawable.pic13,
R.drawable.pic14,
R.drawable.pic15,
R.drawable.background
};
}
Can anyone please help me solve this so I can successfully switch the images within the grid? Thanks.
Upvotes: 3
Views: 2210
Reputation: 1756
In onCreate you are doing:
gridview.setAdapter(new ImageAdapter(this));
So, you created adapter, without assign it to any variable. This is wrong!
Then, every swap you create new Adapter:
ImageAdapter updater = new ImageAdapter(this);
And you are setting it as current adapter:
gridview.setAdapter(updater);
This is wrong as well.
You must do in such a way:
And then, if you have a problem, debug your logic in SWAP method.
//GRID VIEW
public class MainActivity extends ActionBarActivity {
int masterTilePos = 15;
GridView gridview;
ImageAdapter imageAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
imageAdapter= new ImageAdapter(this);
gridview.setAdapter(imageAdapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
//These methods check if a neighboring tile is white, if there is one, swap() is called
if(checkUp(position) || checkDown(position) || checkLeft(position) || checkRight(position)) {
swap(position);
}
}
});
}
public void swap(int pos) {
//This is where I try to switch the images, and seems to be the source of the problem
int val = imageAdaptor.mThumbIds[masterTilePos];
imageAdapter.mThumbIds[masterTilePos] = imageAdapter.mThumbIds[pos];
imageAdapter.mThumbIds[pos] = val;
imageAdapter.notifyDataSetChanged();
gridview.invalidateViews();
masterTilePos = pos;
}
}
//IMAGE ADAPTER
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels / 4;
int height = metrics.heightPixels / 4;
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(width, height));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(1, 1, 1, 1);
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// the array containing references to the images
public Integer[] mThumbIds = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7,
R.drawable.pic8,
R.drawable.pic9,
R.drawable.pic10,
R.drawable.pic11,
R.drawable.pic12,
R.drawable.pic13,
R.drawable.pic14,
R.drawable.pic15,
R.drawable.background
};
}
Upvotes: 4