如何在 GridView 中交换图像 (Android)
How to swap images in a GridView (Android)
我正在开发一个滑块拼图 Android 应用程序,因此我使用 GridView 来显示 16 个代表图块的图像。其中一个图块将由纯白色图像(代表背景)组成。这个想法是,如果用户单击与白色瓷砖相邻的任何瓷砖,则所选瓷砖和白色瓷砖将交换位置。
我试图通过将白色图块设置为用户选择的图块来实现这一点,反之亦然。我将白色图块的位置(它从位置 15 开始)保存在变量 masterTilePos 中,并使用 ImageAdapter Integer 数组引用我的 R.drawable 文件中的图像,将 masterValPos 中的图像设置为选定的索引,并将选定的图像添加到白色图块。但是,当我 运行 程序时,图块仅在第一次成功切换:之后,它无法正常工作并且 GridView 中图块的顺序被破坏。我认为这可能是因为数组只是指实际的图像对象,但我不确定该怎么做;我 运行 进入这个问题已经三天了。这是我的代码:
//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
};
}
谁能帮我解决这个问题,这样我就可以在网格内成功切换图像了?谢谢。
在 onCreate 中你正在做的事情:
gridview.setAdapter(new ImageAdapter(this));
因此,您创建了适配器,但没有将其分配给任何变量。这是错误的!
然后,每次交换都会创建新的适配器:
ImageAdapter updater = new ImageAdapter(this);
并且您将其设置为当前适配器:
gridview.setAdapter(updater);
这也是错误的。
你必须这样做:
- OnCreate -> 创建适配器,将其分配给对象的变量 (属性)
- 然后你只需要使用那个变量。
然后,如果您遇到问题,请在 SWAP 方法中调试您的逻辑。
//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
};
}
我正在开发一个滑块拼图 Android 应用程序,因此我使用 GridView 来显示 16 个代表图块的图像。其中一个图块将由纯白色图像(代表背景)组成。这个想法是,如果用户单击与白色瓷砖相邻的任何瓷砖,则所选瓷砖和白色瓷砖将交换位置。
我试图通过将白色图块设置为用户选择的图块来实现这一点,反之亦然。我将白色图块的位置(它从位置 15 开始)保存在变量 masterTilePos 中,并使用 ImageAdapter Integer 数组引用我的 R.drawable 文件中的图像,将 masterValPos 中的图像设置为选定的索引,并将选定的图像添加到白色图块。但是,当我 运行 程序时,图块仅在第一次成功切换:之后,它无法正常工作并且 GridView 中图块的顺序被破坏。我认为这可能是因为数组只是指实际的图像对象,但我不确定该怎么做;我 运行 进入这个问题已经三天了。这是我的代码:
//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
};
}
谁能帮我解决这个问题,这样我就可以在网格内成功切换图像了?谢谢。
在 onCreate 中你正在做的事情:
gridview.setAdapter(new ImageAdapter(this));
因此,您创建了适配器,但没有将其分配给任何变量。这是错误的!
然后,每次交换都会创建新的适配器:
ImageAdapter updater = new ImageAdapter(this);
并且您将其设置为当前适配器:
gridview.setAdapter(updater);
这也是错误的。
你必须这样做:
- OnCreate -> 创建适配器,将其分配给对象的变量 (属性)
- 然后你只需要使用那个变量。
然后,如果您遇到问题,请在 SWAP 方法中调试您的逻辑。
//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
};
}