简体   繁体   English

Android:在适配器中的触摸事件上更新 GridView 中的图像

[英]Android : Update Image in GridView on touch event in Adapter

I have a GridView and attached adapter to it.我有一个GridView和附加的适配器。 Adapter populates images in the grid.适配器在网格中填充图像。 I have set setOnTouchLister to GridView in my Activity and implemented in the adapter only.我已经在我的Activity中将setOnTouchLister设置为GridView并仅在适配器中实现。 In adapter I have an Integer[] imageIDs that contains resource ids of all images that are added & an ArrayList<ImageSourceObject> imgObjsArr that extends ImageView & has other properties set.在适配器中,我有一个Integer[] imageIDs ,其中包含添加的所有图像的资源 ID,以及一个ArrayList<ImageSourceObject> imgObjsArr ,它扩展了ImageView并设置了其他属性。

Now onTouch() , I want to change the image of the selected image to other one.现在onTouch() ,我想将所选图像的图像更改为其他图像。 Here's my code : SEtting adapter of grid in Activity in onCreate :这是我的代码:在onCreate Activity中设置网格适配器:

        // Set Objects in Game View
    gameView = (GridView) this.findViewById(R.id.game_gridView);
    gameObjAdapter = new GameObjectsAdapter(this, R.id.game_gridView, null);
    gameView.setAdapter(gameObjAdapter);

ADAPTER :适配器 :

public class GameObjectsAdapter extends BaseAdapter implements OnTouchListener {
    super();
    mContext = c;
    this.layoutResourceId = layoutResourceId;
    objects = data;
    gridViewResAdap = (GridView) mContext.findViewById(this.layoutResourceId);
    createObjectsArray();
    Log.d("GOA", "Created Objects Array");
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ImageSourceObject imgView;

    if (convertView == null) {
        imgView = new ImageSourceObject(mContext);
        imgView.setLayoutParams(new GridView.LayoutParams(20, 20));
        imgView.getScaleType();
        imgView.setScaleType(ScaleType.FIT_XY);
        imgView.setPadding(0, 0, 0, 0);
    } else {
        imgView = (ImageSourceObject) convertView;
    }

    // Chk status of touched of imgView & set image accordingly
    if (imgView.isTouched())
        imgView.setImage(R.drawable.droid_touched2);
    else 
        imgView.setImage(imageIds[position]);

    return imgView;
}   

@Override
public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub

    int action = event.getActionMasked();
    float currentXPos = event.getX();
    float currentYPos = event.getY();
    int position = gridViewResAdap.pointToPosition((int)currentXPos, (int) currentYPos);

    // Key was Pressed Here
    if (action == MotionEvent.ACTION_UP) {
        if (position > 0) {
            // Get the object which is clicked
            ImageSourceObject isb = this.imgObjsArr.get(position);
            Log.d("GA", " Postion ID " + isb.getId() + " [] ID : " + imageIds[position]);

            // Change the status of touched & set image
            isb.setTouched(true);
            isb.setImage(R.drawable.droid_touched2); 

            // Update the ArrayList & Integer[] with this updated obj 
            this.imgObjsArr.set(position, isb);
            imageIds[position] = R.drawable.droid_touched2;
            Log.d("ISB", "++++ Object ID : " + isb.getId() + " [] ID : " + imageIds[position] + " ISB Touched :" + isb.isTouched());

            Toast.makeText(mContext, "Postion Pressed : " + (position+1), 
                Toast.LENGTH_SHORT).show();

            //this.gridViewResAdap.invalidate();
        }

        return true;
    }

    return false;
}

Logs :日志:

02-19 15:19:11.615: D/GA(2046):  Postion ID 2130837556 [] ID : 2130837556
02-19 15:19:11.617: D/ISB(2046): ++++ Object ID : 2130837559 [] ID : 2130837559 ISB Touched :true

The logs say that the object in Integer[] & ArrayList both are updated & have right values.日志说Integer[]ArrayList中的对象都已更新并具有正确的值。 After all this also the image is not updated on the screen.毕竟,图像也不会在屏幕上更新。 The gridViewResAdap is also the object of grid that is passed from the activity. gridViewResAdap也是从活动传递过来的网格对象。 I tried calling invalidate() on it also, but yet no results.我也尝试在其上调用invalidate() ,但没有结果。 As in my getView() , I am using imageIDs , so I have kept that also updated.和我的getView() ,我使用的是imageIDs ,所以我也保持更新。

ImageSourceObject :图像源对象:

public class ImageSourceObject extends ImageView {

public void setImage(int resourceId) {
    super.setImageResource(resourceId);
    this.setId(resourceId);
}

Also, onTouch() gives error to call onPerformClick() , I am not sure where to call & why to call.此外, onTouch()调用onPerformClick()时出错,我不确定在哪里调用以及为什么调用。 I have alos not implemented onClickListener in the adapter.我还没有在适配器中实现onClickListener What can be done in this case & what to write in onClickListener when things are manged in onTouch() .在这种情况下可以做什么onClickListener当事情在onTouch()中管理时在onTouch()写什么。

Can you help me know why the image object is not updating and where am I going wrong ?你能帮我知道为什么图像对象没有更新以及我哪里出错了吗? I thought I have to refresh the grid, so have also called invalidate(), but no results.我以为我必须刷新网格,所以也调用了 invalidate(),但没有结果。

Any help is highly appreciated.任何帮助都受到高度赞赏。

Thanks谢谢

You can simply do:你可以简单地做:

@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub

int action = event.getActionMasked();
float currentXPos = event.getX();
float currentYPos = event.getY();
int position = gridViewResAdap.pointToPosition((int)currentXPos, (int) currentYPos);

// Key was Pressed Here
if (action == MotionEvent.ACTION_UP) {
    if (position > 0) {
       ((ImageView)v).setImageDrawable(ctx.getResources().getDrawable(R.drawable.droid_touched2));
    }

    return true;
}

return false;

} }

After your ImageView begins handling the TouchEvent, it is the only view allowed to do anything with that touch gesture.在您的ImageView开始处理 TouchEvent 之后,它是唯一允许使用该触摸手势执行任何操作的视图。 You want your GridView to intercept the TouchEvent, check the X and Y coordinates of the TouchEvent ( event.getX(); event.getY() ) and see if those coordinates fall within the bounds of one of your ImageView objects.您希望GridView拦截 TouchEvent,检查 TouchEvent 的 X 和 Y 坐标( event.getX(); event.getY() )并查看这些坐标是否落在您的ImageView对象之一的范围内。 If yes, set a flag on the ImageView or something that can trigger your setImageDrawable() method.如果是,请在ImageView或可以触发setImageDrawable()方法的东西上设置一个标志。 I was able to achieve a similar effect in one of my projects but I had to create a custom GridView class ( public class yourGridView extends GridView ), then override the following:我能够在我的一个项目中实现类似的效果,但我必须创建一个自定义 GridView 类( public class yourGridView extends GridView ),然后覆盖以下内容:

@Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch(action) {
            case MotionEvent.ACTION_DOWN:
                Log.i(AGL, "InterceptAction = DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i(AGL, "InterceptAction = MOVE");
                break;
            case MotionEvent.ACTION_CANCEL:
                Log.i(AGL, "InterceptAction = CANCEL");
                return false;
        }
        return true;  //returning true tells your main Activity that you want the custom GridView to handle this TouchEvent; It will then send the TouchEvent to your GridView's onTouchEvent() method for handling.
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch(action) {
            case MotionEvent.ACTION_MOVE:
                int xCoord = (int) event.getX();
                int yCoord = (int) event.getY();
                Log.i(AGL, "MOVE EVENT;" + "\n" +  "Touch X = " + Integer.toString(xCoord) + "\n" +
                "Touch Y = " + Integer.toString(yCoord));
                for(int i = 0; i < this.getChildCount(); i++) {
                    ImageView suspect = (ImageView) this.getChildAt(i);
                    if(suspect.getBounds().contains(xCoord, yCoord)) {
                        suspect.CHANGE_YOUR_IMAGE_HERE();
                        suspect.invalidate();
                    }
                }
                break;
        }

        return true;
    }

PLEASE NOTE: getBounds() is a method I wrote in my custom ImageView class.请注意:getBounds() 是我在自定义ImageView类中编写的方法。 This method returns a Rect object that represents the bounding box of the ImageView object.此方法返回一个 Rect 对象,该对象表示ImageView对象的边界框。 You will have to use your own logic for fetching the bounds of your ImageView .您必须使用自己的逻辑来获取ImageView的边界。

ALSO NOTE: When I run this logic in my project, my ImageView s change images rapidly during the touch gesture.另请注意:当我在我的项目中运行此逻辑时,我的ImageView在触摸手势期间快速更改图像。 I haven't figured out yet how to limit it to one image change per MotionEvent.ACTION_MOVE.我还没有想出如何将它限制为每个 MotionEvent.ACTION_MOVE 一个图像更改。

I hope this helps.我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM