Схема сетки кнопок значков/текста

Я пытаюсь создать сетку 3 x 3 элементов. Каждый элемент состоит из ImageView поверх TextView. К сожалению, у меня возникают проблемы с тем, чтобы все было хорошо.

Вот моя попытка собрать 2 таких предмета бок о бок. Текстовые представления даже не отображаются, и значки сжимаются вместе (вместо равномерного разнесения)

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1" android:gravity="center"
    android:paddingLeft="40px" android:paddingRight="40px" >
<TableRow>
    <LinearLayout android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
        <ImageView 
           android:id="@+id/usertoolsimage"
           android:src="@drawable/ftnicon"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           />
        <TextView
        android:text="User Accounts"
        android:gravity="right"
        android:padding="3dip" android:textColor="#ffffff" />
    </LinearLayout>


   <LinearLayout android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
        <ImageView 
           android:id="@+id/queueimage"
           android:src="@drawable/ftnicon"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           />
        <TextView
        android:text="Queue Management"
        android:gravity="right"
        android:padding="3dip" android:textColor="#ffffff" />
    </LinearLayout>
</TableRow>

<TableRow>
    <TextView
        android:text="test 3"
        android:padding="3dip" android:textColor="#ffffff" />
    <TextView
        android:text="test 4"
        android:gravity="right"
        android:padding="3dip" android:textColor="#ffffff" />
</TableRow>
</TableLayout>

Моя цель в конце концов - иметь сетку кликабельных элементов, где элемент представляет собой изображение и текст для главного меню. Может ли кто-нибудь вести меня о том, какие макеты я должен использовать для достижения этого?

Ответы

Ответ 1

Лучше всего, по моему мнению, использовать gridView таким образом, чтобы он поддерживал прокрутку и интервал, и вы можете быть очень динамичным в том, что касается каждого макета и событий. Другой вариант - просто создать компоновку изображений с комбинацией Relative/Linear Layouts.

Макет GridView:

<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/myGrid"
android:layout_width="match_parent" 
android:layout_height="match_parent"
android:padding="10dp"
android:verticalSpacing="10dp"

android:horizontalSpacing="10dp"
android:numColumns="3"
android:columnWidth="60dp"
android:stretchMode="columnWidth"

android:gravity="center"
/>

а затем в вашей деятельности:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    mGame.status = GameStatus.PLAYING;

    setContentView(R.layout.gridLayout);
    GridView grid = (GridView) findViewById(R.id.myGrid);
    grid.setAdapter(new customAdapter());

    grid.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            //do some stuff here on click
        }
    });
}

public class customAdapter extends BaseAdapter {

    public View getView(int position, View convertView, ViewGroup parent) {
//create a basic imageview here or inflate a complex layout with
//getLayoutInflator().inflate(R.layout...)
        ImageView i = new ImageView(this);

        i.setImageResource(mFams.get(position).imageId);
        i.setScaleType(ImageView.ScaleType.FIT_CENTER);
        final int w = (int) (36 * getResources().getDisplayMetrics().density + 0.5f);
        i.setLayoutParams(new GridView.LayoutParams(w * 2, w * 2));
        return i;
    }

    public final int getCount() {
        return 9;
    }

    public final Family getItem(int position) {
        return mFams.get(position);
    }

    public final long getItemId(int position) {
        return position;
    }
}

Или базовый макет с использованием линейных макетов:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout android:id="@+id/linearLayout1" 
android:layout_height="fill_parent" 
android:layout_weight="1"
android:layout_alignParentLeft="true" 
android:layout_width="fill_parent"
android:orientation="horizontal">

    <ImageView>...</ImageView>
    <ImageView>...</ImageView>
    <ImageView>...</ImageView>

</LinearLayout>

<LinearLayout android:id="@+id/linearLayout2" 
android:layout_height="fill_parent" 
android:layout_weight="1"
android:layout_alignParentLeft="true" 
android:layout_width="fill_parent"
android:orientation="horizontal">

    <ImageView>...</ImageView>
    <ImageView>...</ImageView>
    <ImageView>...</ImageView>

</LinearLayout>

<LinearLayout android:id="@+id/linearLayout3" 
android:layout_height="fill_parent""
android:layout_weight="1"
android:layout_alignParentLeft="true" 
android:layout_width="fill_parent"
android:orientation="horizontal">

    <ImageView>...</ImageView>
    <ImageView>...</ImageView>
    <ImageView>...</ImageView>

</LinearLayout>

Ответ 2

Вы действительно должны использовать GridView для создания сеток, а не для TableRows. Вы видели учебник Android для GridView? Чтобы иметь возможность добиться того, что вы хотите, с изображением, наложенным на текст, вам нужно будет использовать FrameLayout как приведенный в пример Android FrameLayout. Однако сложная часть заключается в том, что вам нужно применить этот макет к каждому элементу, который будет находиться в Gridview.

Так, например, скажем, вы создаете файл макета с именем image_text_view.xml, который выглядит так:

    <FrameLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:id="@+id/gridImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="false">
</ImageView>
<CheckedTextView
android:id="@+id/imageTick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textColor="#000000"
android:layout_gravity="center_horizontal|bottom"
android:checkMark="@drawable/icon"
android:checked="false"
android:visibility="invisible"
>
</CheckedTextView>
</FrameLayout>

Вам нужно применить этот макет в каждом элементе GridView. Для этого (редактирование примера GridView для Android) Вам нужно будет переопределить getView в ImageAdapter следующим образом:

public View getView(int position, View convertView, ViewGroup parent) {
View v;
    if(convertView==null){
        v = LayoutInflater.from(mContext).inflate(R.layout.image_text_view,null);
        v.setLayoutParams(new GridView.LayoutParams(100,100));

        ImageView imageView = (ImageView)v.findViewById(R.id.image);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);
        imageView.setImageResource(mThumbsIds[position]);

                    CheckedTextView checkedTextView = (TextView) v.findViewById(R.id.imageTick);
                    checkedTextView.setEnabled(true);
                    checkedTextView.setVisibility(View.VISIBLE);

    }
    else
    {
        v = convertView;
    }


    return v;

Используя это, например, вы будете иметь все, что вы установили (будь то его текст или значки), накладывающие изображения для каждого элемента в сетке. Вам может потребоваться внести небольшие изменения в этот пример для удовлетворения ваших конкретных потребностей, но это та стратегия, с которой я бы пошел.