Проблемы с событием клика в TableLayout

Доброе утро всем,

Я столкнулся с еще одной проблемой на моем пути изучения Android. Я сделал динамический TableLayout с содержимым файла CSV. Мне нужно, чтобы, когда я нажимаю/касаюсь строки в таблице, цвет должен меняться, а затем нажатием кнопки получать содержимое той же строки. Теперь я застрял в первой части и, конечно, понятия не имею, как получить данные строки.

Я объявил таблицу внутри LinearLayout, которая также находится внутри ScrollView в моем макете со следующими свойствами:

    <ScrollView
    android:id="@+id/scrollMotors"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:layout_alignParentBottom="true"
    android:layout_marginLeft="50dp"
    android:layout_marginRight="50dp"
    android:layout_marginTop="90dp"
    android:layout_marginBottom="50dp" >
    <LinearLayout
        android:id="@+id/layoutMotors"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <TableLayout
            android:id="@+id/tableMotors"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:gravity="center_vertical"
            android:stretchColumns="*" >

        </TableLayout>
    </LinearLayout>
</ScrollView>

После того, как в моем java-коде я объявил создание строки:

        //Initialization of my table
    my_tableMotors = (TableLayout) findViewById(R.id.tableMotors);
    //This is an ArrayList<ArrayList<String>> that contains the lines of the CSV file,
    //I use this variable as a dynamic Matrix because my CSV file can change its dimensions.
    m = valuesFile.size(); 
    for (n = 0 ; n < m ; n++)
    {
        //Declaration and initialization of my rows
        final TableRow line = new TableRow(MotorActivity.this);
        //Setting the parameters of my row
        line.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
        line.setFocusable(true);
        line.setFocusableInTouchMode(true);
        line.setClickable(true);
        //Initialization of my TextViews that are gonna be the content of each one of the rows in the dynamic TableLayout
        myCol1 = new TextView(MotorActivity.this);
        myCol2 = new TextView(MotorActivity.this);
        myCol3 = new TextView(MotorActivity.this);
        myCol4 = new TextView(MotorActivity.this);
        j = valuesFile.get(n).size();
        for (i = 0 ; i < j ; i++)
        {
            switch(i)
            {
            case 0: 
                if (n == 0)
                {
                    myCol1.setText("Line");
                }
                else
                {
                    myCol1.setText(valuesFile.get(n).get(i)); //Sets value for the column
                }
                line.addView(myCol1);
                break;
            case 1:
                myCol2.setText(valuesFile.get(n).get(i)); //Sets value for the column
                line.addView(myCol2);
                break;
            case 2:
                myCol3.setText(valuesFile.get(n).get(i)); //Sets value for the column
                line.addView(myCol3);
                break;
            case 3:
                myCol4.setText(valuesFile.get(n).get(i)); //I use this variable for some other purpose
                break;
            }
        }
        my_tableMotors.addView(line);
    }
    my_tableMotors.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {onClickedRow(); }});
}

Из того, что я видел и читал здесь, лучше всего использовать setOnClickListener, и это то, что я сделал, используя два разных ответа, которые я нашел здесь:

    public void onClickedRow()
{
    m = my_tableMotors.getChildCount();
    for (n = 0 ; n < m ; n++)
    {
        if (my_tableMotors.getChildAt(n).hasFocus())
        {
            my_tableMotors.setBackgroundColor(myColor);
        }
    }
}

Теперь я вообще не могу сфокусироваться на tableLayout, поэтому, пожалуйста, если вы видите что-то не так в моем коде или если вы знаете, как мне помочь с этим, я был бы вам очень признателен!!!!

Спасибо заранее :).

ИЗМЕНИТЬ 1

Я нашел способ получить фокус. Я изменил метод не на весь TableLayout, а только на TableRow, так что получилось так:

*До*

        my_tableMotors = (TableLayout) findViewById(R.id.tableMotors);
    m = valuesFile.size(); 
    for (n = 0 ; n < m ; n++)
    {
        //Declaration and initialization of my rows
        final TableRow line = new TableRow(MotorActivity.this);
        /*Other declarations*/
        j = valuesFile.get(n).size();
        for (i = 0 ; i < j ; i++)
        {
            /*Code*/
        }
        my_tableMotors.addView(line);
    }
    my_tableMotors.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {onClickedRow(); }});
}

*После*

    my_tableMotors = (TableLayout) findViewById(R.id.tableMotors);
m = valuesFile.size();
for (n = 0 ; n < m ; n++)
{
    //Declaration and initialization of my rows
        final TableRow line = new TableRow(MotorActivity.this);
    /*Other declarations*/
    j = valuesFile.get(n).size();
    for (i = 0 ; i < j ; i++)
    {
        /*Code*/
    }
    line.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {onClickedRow(); }});
    my_tableMotors.addView(line);
}

Я также внес изменения в способ установки цвета линии:

*До*

my_tableMotors.setBackgroundColor(myColor);

*После*

my_tableMotors.getChildAt(n).setBackgroundResource(R.drawable.myColor);

Сейчас я занят выяснением того, как получить данные из TableRow. Как только я получу это решение или ответ от вас, я думаю, что моя проблема решена!!!

ИЗМЕНИТЬ 2

С помощью @Luksprog я смог найти ответ на мою проблему с получением контента!!! Я использовал следующий код, используя его решение:

    public void onClickedRow()
{
    TableRow clickedRow = new TableRow(MotorActivity.this);
    m = my_tableMotors.getChildCount();
    for (n = 1 ; n < m ; n++)
    {
        if (my_tableMotors.getChildAt(n).isFocused())
        {
            my_tableMotors.getChildAt(n).setBackgroundResource(R.drawable.highlightTableRow);
            clickedRow = (TableRow) my_tableMotors.getChildAt(n);
            j = clickedRow.getChildCount();
            for (i = 0; i < j ; i++)
            {
                switch(i)
                {
                case 0:
                    myField1 = (TextView) clickedRow.getChildAt(i);
                    break;
                case 1:
                    myField2 = (TextView) clickedRow.getChildAt(i);
                    break;
                case 2:
                    myField3 = (TextView) clickedRow.getChildAt(i);
                    break;
                }
            }
        }
    }
}

person Marialvy Martínez    schedule 19.09.2012    source источник


Ответы (2)


Не устанавливайте OnClickListener в TableLayout, вместо этого установите его для каждого TableRow, который вы создаете в этом цикле for:

for (n = 0 ; n < m ; n++) {
    //Declaration and initialization of my rows
    final TableRow line = new TableRow(MotorActivity.this);
    line.setOnClickListener(mListener);
    line.setId(1000 + n);
    // ...

где mListener:

OnClickListener mListener = new OnClickListener() {

     public void onClick(View v) {
         // v is the TableRow that was clicked
         v.setBackgroundColor(Color.RED);
         // mClickedPosition is a int field representing the clicked row(to know the position later)
         // if you allow more than one row to be clicked at one time, use a list of ints
         // or something like this
         mClickedPosition = v.getId() - 1000; 
     }
}

Чтобы позже получить содержимое строки, вы должны использовать переменную mClickedPosition:

TableRow clickedRow = (TableRow) my_tableMotors.getChildAt(mClickedPosition);
// having the child TableRow that was clicked you could extract any data you want from it
// of course you could simply use the mClickedPosition to extract the data from whatever data structure you have(I'm looking at valuesFile)
person user    schedule 19.09.2012
comment
Да, я только что увидел это, я внес правку в свой пост. Большое спасибо за ваш ответ!!!! Я попробую последний код, который вы опубликовали, чтобы получить контент, чтобы увидеть, работает ли он :). - person Marialvy Martínez; 19.09.2012
comment
большое спасибо за ваш пост!!!! Вы можете увидеть, как я использовал его во втором редактировании моей темы. - person Marialvy Martínez; 19.09.2012

Вы можете изменить следующий код в соответствии с вашими требованиями. Вот и все:-

public void createTable() {
        TableLayout table = (TableLayout) findViewById(R.id.tableMotors);
        table.removeAllViewsInLayout();

        List<String> namesList = new ArrayList<String>();
        namesList.add("name");
        namesList.add("name2");
        namesList.add("name3");

        // display dynamic table rows
        for (int counter = 0; counter < namesList.size(); counter++) {
            TableRow row = new TableRow(this);

            // add the index view to the row
            TextView index = new TextView(this);
            index.setLayoutParams(new LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            index.setId(100);
            index.setTextColor(Color.RED);
            String indexString = String.valueOf(counter + 1);
            index.setText(indexString);

            // textview to display names
            final TextView nameView = new TextView(this);
            nameView.setLayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            nameView.setId(0);
            nameView.setText(namesList.get(counter));
            nameView.setTextColor(Color.RED);

            RelativeLayout relativeRowContent = new RelativeLayout(this);

            // set the layout params for the control to be added
            RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
                    android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT,
                    android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);
            rlp.setMargins(10, 0, 0, 0);
            rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            relativeRowContent.addView(index, rlp);

            // add the divider after index
            final TextView indexDivider = new TextView(this);
            indexDivider.setWidth(1);
            indexDivider.setId(101);
            indexDivider.setHeight(80);
            indexDivider.setBackgroundColor(Color.GRAY);

            // display the index
            rlp = new RelativeLayout.LayoutParams(
                    android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT,
                    android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);
            rlp.setMargins(80, 0, 0, 0);
            rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            relativeRowContent.addView(indexDivider, rlp);

            // set the layout params for the control to be added
            rlp = new RelativeLayout.LayoutParams(
                    android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT,
                    android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);
            rlp.setMargins(10, 0, 0, 0);
            rlp.addRule(RelativeLayout.RIGHT_OF, indexDivider.getId());
            relativeRowContent.addView(nameView, rlp);

            // finally add the relative row content layout in the table row.
            row.addView(relativeRowContent);
            /* row.setBackgroundResource(R.drawable.row_border_light); */

            // add the row to the table.
            table.addView(row, new TableLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            row.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    Toast.makeText(TestActivity.this,
                            "" + nameView.getText().toString(),
                            Toast.LENGTH_SHORT).show();

                    // or do something more use full here.

                }
            });

        }
    }
person Chandrashekhar    schedule 19.09.2012