How to handle the onclick map button in a gridview? Best practice

I am trying to find the best solution for handling the event OnClickthat is generated by the button of my card (see the figure below) within GridView.

my card and button on it

So, as you can see, I have a regular one GridViewwith cells made from my custom Map.

I just initialize GridViewand its adapter:

mGrid = (GridView) findViewById(R.id.grid);
mAdapter = new ImageTopicsAdapter(..blah blah blah..);
mGrid.setAdapter(mAdapter);

As you probably know, I can easily handle the events OnClickgenerated GridView. But it will only work if I click on the map:

mGrid.setOnItemClickListener(..blah blah blah..);

I want to create something similar to this (see the code below), so I can easily "implement" my Activityto handle the button of my OnClickevent card :

mGrid.setOnItemButtonClickListener(..blah blah blah..);

What is the best way (clean \ easy \ elegant)?

. . :)

+4
3

, , . @Dimitar G. @Konstantin Kiriushyn. , .

1). CardView Compound View, : LinearLayout + ImageView + TextView + Button.

public class TopicCardView extends LinearLayout {

   private ImageView mImage;
   private Button mButtonMenu;
   private TextView mTitle;

   public TopicCardView (Context context) {
      initializeViews(context);
   }

   private void initializeViews(Context context) {
      LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      inflater.inflate(R.layout.topic_card_view, this);
   }

   private void setTitle(...) {
      ...
   }

   private void setImage(...) {
      ...
   }

   private void setMenuClickListener(...) {
      ...
   }

   // and so on...
}

2) createListOfGridCardsFromDB(...) Activity\Fragment. (LinkedList) CardView ( \ CardView s).

3) LinkedList CardView GridViewAdapter.

. , , .. Adapter.

0

, . ( ):

  • , ArrayAdapter

    • , ( )
    • ( )
    • context ApplicationActivity , - , ,

      private final MyAdapter extends ArrayAdapter implements View.OnClickListener {
          @Override
          public View getView(int position, View convertView, ViewGroup parent) {
              // inflate your card then get a reference to your button
              View card = ....;
              card.findViewById(R.id.YOUR_BUTTON_ID).setOnClickListener(this);
              return card;
          }
      
          @Override
          public void onClick(View view) {
              ApplicationActivity activity = (ApplicationActivity) view.getContext();
              if (activity != null && !activity.isFinishing()) {
                  applicationActivity.onCardButtonClick();
              }
          }
      }
      
      // in your ApplicationActivity
      public final class ApplicationActivity extends Activity {
          ...
      
          public void onCardButtonClick() {
              // deal with your click
          }
      }
      

textbook ( ..), , .

.

View ( ), . , .

BTW. , " " ( , ), (-)/p >

, , , . , , , :

public final MyAdapter extends ArrayAdapter {
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // inflate your card then get a reference to your button
        View card = ....;
        card.findViewById(R.id.YOUR_BUTTON_ID).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ApplicationActivity activity = (ApplicationActivity) view.getContext();
                if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
                    applicationActivity.onCardButtonClick();
                }
            }
        });
        return card;
    }
}

-

, . :

public class ApplicationActivity extends Activity {
    ....

    public void onCardButtonClick(Cell cell) {
        // do whatever you want with the model/view
    }
}

// ViewModel instances are used in your adapter
public final class ViewModel {
    public final String description;
    public final String title;

    public ViewModel(String title, String description) {
        this.title = title != null ? title.trim() : "";
        this.description = description != null ? description.trim() : "";
    }
}

public final class Cell extends LinearLayout {
    private View button;
    private ViewModel model;

    // ViewModel is data model and is the list of items in your adapter
    public void update(ViewModel model) {
        this.model = model;
        // update your card with your model
    }

    public ViewModel getModel() {
        return model;
    }

    @Override
    protected void onAttachedToWindow() {
        button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener {
            @Override
            public void onClick(View view) {
                ApplicationActivity activity = (ApplicationActivity) view.getContext();
                if (model != null && activity != null && !activity.isFinishing() && !activity.isDestroyed() {
                    activity.onCardButtonClick(Cell.this);
                }
            }
        });
    }
}

// then your adapter `getView()` needs to inflate/create your compound view and return it
public final MyAdapter extends ArrayAdapter {
    private final List<ViewModel> items;

    public MyAdapter() {
        // update your models from outside or create on the fly, etc.
        this.items = ...;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {        
            // inflate - say it is a layout file 'cell.xml'
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell);
        }

        ((Cell) convertView).update(items.get(position));
        return convertView;
    }
}
+2

. , setOnOptionsClickListener ( OnOptionsClickListener), , .

, Activity/Fragment

public interface OnOptionsClickListener {
      void onOptionsClicked(View view, PictureItem item);
}


mAdapter= new MyGridAdapter();
mAdapter.setOnOptionsClickListener(new OnOptionsClickListener() {
       public void onClick(View view, PictureItem item) {
            //process click
       }
});

public void setOnOptionsClickListener(OnOptionsClickListener l) {
    mOnOptionsClickListener = l;
}

findViewById(R.id.btn_options).setOnClickListener(new OnClickListener(){
    public void OnClick(View view) {
        mOnOptionsClickListener.onOptionsClicked(view, currentPictureItem);
    }
});

.. , OnClick() (, currentPictureItem, URL- ). OnClickListener.

Edit So here is the explanation. Adapterserves for viewing GridViewfor View-provider. It creates views and sets up the base state. Therefore, during initialization of views, all clicks must be set to Adapter. Moreover, we do not want to have messy Activitywith a nested Adapter, but we want Adapter to be a separate class. For this reason, you usually need to create an additional interface in order to have access to the object currentItemto retrieve data.

+1
source