web-dev-qa-db-fra.com

Une disposition en grille de boutons icône / texte

J'essaie de créer une grille d'éléments 3 x 3. Chaque élément se compose d'un ImageView au-dessus d'un TextView. Malheureusement, j'ai des problèmes pour que tout fonctionne correctement.

Voici ma tentative d'obtenir 2 de ces éléments côte à côte. Les vues de texte ne s'affichent même pas et les icônes sont écrasées ensemble (au lieu d'être régulièrement espacées)

<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>

Mon objectif final est d'avoir une grille d'éléments cliquables où l'élément est une image et du texte pour un menu principal. Quelqu'un peut-il me guider sur les dispositions que je dois utiliser pour y parvenir?

16
Josh

À mon avis, votre meilleur pari serait d'utiliser le gridView de cette façon, il prend en charge le défilement et l'espacement et vous pouvez être très dynamique dans la disposition et les événements de chaque élément. Une autre option consiste simplement à créer une disposition des images avec une combinaison de dispositions relatives/linéaires.

Disposition 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"
/>

puis dans votre activité:

@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;
    }
}

Ou la disposition de base en utilisant des dispositions linéaires:

<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>
30
Patrick Kafka

Vous devriez vraiment utiliser une GridView pour faire des grilles, et non des TableRows. Avez-vous vu le tutoriel d'Android pour GridView? Pour pouvoir réaliser ce que vous voulez avec une image superposée avec du texte, vous devez utiliser FrameLayout comme indiqué dans exemple FrameLayout d'Android. = La partie délicate ici, cependant, est que vous devez appliquer cette mise en page à chaque élément qui va être dans la Gridview.

Ainsi, par exemple, supposons que vous créez un fichier de mise en page appelé image_text_view.xml qui ressemble à ceci:

    <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>

Vous devez appliquer cette disposition dans chacun de vos éléments GridView. Pour ce faire (modification de l'exemple GridView d'Android), vous devez redéfinir le getView dans ImageAdapter comme suit:

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;

En utilisant cela, par exemple, vous aurez tout ce que vous définissez (que ce soit son texte ou ses icônes) superposant les images pour chaque élément de la grille. Vous devrez peut-être apporter des modifications mineures à cet exemple pour répondre à vos besoins exacts, mais c'est la stratégie que j'adopterais.

6
Hakan Ozbay