【问题标题】:How to swap images in a GridView (Android)如何在 GridView (Android) 中交换图像
【发布时间】:2015-04-07 22:05:11
【问题描述】:

我正在开发一个滑块拼图 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


  };

}

谁能帮我解决这个问题,以便我可以成功切换网格内的图像?谢谢。

【问题讨论】:

  • 为什么每次进行交换时都会创建新的 ImageAdapter?
  • 您正在交换中创建 ImageAdapter 的新实例 .. 这是错误的,您应该创建它的一个实例,然后执行 notifyDataSetChanged()。您无需对其执行setAdapter 或创建另一个实例
  • @Android2390:我不知道...当我不调用 setAdapter 时,没有任何改变或工作
  • @AlexanderRavikovich:我不知道......当我不调用 setAdapter 时没有任何变化或工作

标签: java android android-imageview android-adapter android-gridview


【解决方案1】:

在 onCreate 你正在做的事情:

gridview.setAdapter(new ImageAdapter(this));

因此,您创建了适配器,但没有将其分配给任何变量。这是错误的!

然后,每次交换你创建新的适配器:

ImageAdapter updater = new ImageAdapter(this);

您将其设置为当前适配器:

gridview.setAdapter(updater);

这也是错误的。

你必须这样做:

  1. OnCreate -> 创建适配器,将其分配给对象的变量(属性)
  2. 那么您只需要使用该变量即可。

然后,如果您有问题,请在 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
  };
}

【讨论】:

  • 好的,谢谢,您还知道我在交换方法中还能做什么吗?因为我不确定我还能使用什么来切换图像。
  • 我不知道您的问题是“adnroid”问题还是您的逻辑有问题。例如。我看不到使用 int masterTilePos = 15; 背后的逻辑。为什么要先存储背景的位置? (数组中有 16 个元素,因此在索引 15 中有 R.drawable.background)
  • 好的,让我解决 ImageAdapter 的问题,然后我会尽快通知您。谢谢。
  • 所以我解决了 ImageAdapter 问题,现在它可以完美运行了!所以交换方法的逻辑很好,但正如你所说,问题在于没有一个通用的 ImageAdapter 对象可以使用。非常感谢您的帮助,非常感谢您,先生!
猜你喜欢
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多