Лучший способ передать кнопку onClick обратно к основной деятельности? - PullRequest
2 голосов
/ 06 сентября 2011

У меня есть супер приложение TestUI.У него есть вид сетки с кнопками в них.

Я хочу, чтобы слово нажатия кнопки было передано обратно в основное действие, чтобы оно могло обновлять свое состояние.

К сожалению, кнопки крадут щелчки.Так что типичное:

        gridview.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                Toast.makeText(TestUI.this, "" + position, Toast.LENGTH_SHORT).show();
            }
        });

Не вызывается.

Вместо этого в определении адаптера:

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

    Button gridItem;

    if (convertView == null) {  // if it's not recycled, initialize some attributes
        gridItem = new Button(mContext);
    } else {
        gridItem = (Button) convertView;
    }
    gridItem.setText("button " + String.valueOf(position));
    gridItem.setClickable(true);
    gridItem.setFocusable(false);
    gridItem.setOnClickListener(new MyOnClickListener(position, mContext));

    return gridItem;

, который поддерживается классом MyOnClickListener, который реализует OnClickListenerинтерфейс.Однако, если я делаю это таким образом, мне все равно нужен обратный вызов к основному действию, так или иначе, он должен знать, что что-то было сделано, поскольку он контролирует состояние программы.

Так, каков наилучший способ обновить "root «состояние / деятельность» от нажатия кнопки?

Я знаю, что это основной вопрос ОО, но я в основном пишу на ASM и C, так что, честно говоря, просто не знаю.

Ответы [ 2 ]

1 голос
/ 06 сентября 2011

Зачем вам нужно 2 onClickListeners. От onItemClickListener к основной деятельности вы не можете выполнять всю работу, которая вам нужна? Нужно ли адаптеру выполнять MyOnClickListener работу?

Вы можете установить gridItem.setOnClickListener из основного действия. Нет необходимости каждый раз создавать новый объект ListenerObject.

Вам просто нужен xml для раздувания, чтобы getView содержал Button

  <Button android:text="Handle me"
     android:id="@+id/btnHandleMe"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:onClick="buttonHandler"
     android:clickable="true">

и создайте эту функцию для своей деятельности.

public void buttonHandler(View v) {
        // Do your stuff here that new MyOnClickListener(position, mContext) whould do.
    }

Вы можете получить положение строки / столбца, в котором эта кнопка заполнена в списке / сетке, добавив тег к адаптеру.

В getView добавить

 gridItem.setTag(position)

и извлечь его из кнопки Handler

if(v.getTag instance of Integer)
int position = (Integer)v.getTag();

Итак, теперь вы обрабатываете все клики из действия, и по умолчанию действие уведомляется.

0 голосов
/ 06 сентября 2011

Как вы сказали, ваш метод getView находится внутри класса адаптера. Но адаптер получает копию «контекста», к которому у вашего метода getView есть доступ. Контекст - это суперкласс всех видов деятельности и услуг. С помощью этого объекта вы можете выполнять множество основных операций в Деятельности. Из вашего примера я понимаю, что вы хотели бы показать тост. Это можно сделать с помощью

public View getView(int position, View convertView, ViewGroup parent) {
    //usual getView stuff goes first

    gridItem.setOnClickListener(new OnClickListener(){
        public onClick(View v){
            Toast.makeText(mContext, "" + position, Toast.LENGTH_SHORT).show();
        }
    }
}

Короче говоря, ваш класс MyOnClickListener должен использовать переменную mContext для взаимодействия с корневым действием.

Редактировать Я понял, что сделал ошибку в ответе выше. Я посмотрел пример на http://developer.android.com/resources/tutorials/views/hello-gridview.html и понял, что вы не ограничены в использовании контекста. Вы можете использовать что-то вроде

public class MyActivity extends Activity {
    public int a = 0;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));
    }
}

public class ImageAdapter extends BaseAdapter {
    private MyActivity myAct;
    public ImageAdapter(MyActivity c) {
        myAct= c;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        //usual getView stuff goes first

        gridItem.setOnClickListener(new OnClickListener(){
            public onClick(View v){
                myAct.a = position;
            }
        }
    }
}

Надеюсь, это то, что вы хотели сделать.

...