it-swarm.com.de

Was ist der Hauptzweck der setTag () getTag () - Methoden von View?

Was ist der Hauptzweck solcher Methoden wie setTag() und getTag() von Objekten vom Typ View?

Habe ich Recht damit, dass ich einer Ansicht eine beliebige Anzahl von Objekten zuordnen kann?

403
Eugene

Angenommen, Sie generieren eine Reihe von Ansichten, die ähnlich sind. Sie können für jede Ansicht einzeln ein OnClickListener festlegen:

button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
 ...

Dann müssen Sie für jede Ansicht eine eindeutige onClick -Methode erstellen, auch wenn sie ähnliche Aktionen ausführen, z.

public void onClick(View v) {
    doAction(1); // 1 for button1, 2 for button2, etc.
}

Dies liegt daran, dass onClick nur einen Parameter hat, nämlich View, und dass andere Informationen von Instanzvariablen oder endgültigen lokalen Variablen in umschließenden Bereichen abgerufen werden müssen. Was wir wirklich wollen, ist, Informationen zu erhalten aus den Ansichten selbst.

Geben Sie getTag/setTag ein:

button1.setTag(1);
button2.setTag(2);

Jetzt können wir für jede Schaltfläche den gleichen OnClickListener verwenden:

listener = new OnClickListener() {
    @Override
    public void onClick(View v) {
        doAction(v.getTag());
    }
};

Es ist im Grunde eine Möglichkeit für Ansichten, Erinnerungen zu haben.

613
Matthew Willis

Ich möchte ein paar Worte hinzufügen.

Obwohl die Verwendung von get/setTag(Object) in bestimmten Fällen des ViewHolder-Musters sehr nützlich zu sein scheint, würde ich empfehlen, zweimal darüber nachzudenken, bevor Sie es in anderen Fällen verwenden. Fast immer gibt es eine andere gute Designlösung.

Der Hauptgrund ist, dass Code ziemlich schnell nicht mehr unterstützt werden kann.

  • Für andere Entwickler ist es nicht offensichtlich, was Sie als Tag in der Ansicht gespeichert haben. Die Methoden setTag/getTag sind überhaupt nicht beschreibend.

  • Es wird nur ein Object gespeichert, sodass eine Umwandlung erforderlich ist, wenn Sie getTag möchten. Sie können später einen unerwarteten Absturz bekommen, wenn Sie sich entscheiden, den Typ des gespeicherten Objekts im Tag zu ändern.

  • Dies ist die Geschichte aus dem wirklichen Leben. Wir hatten ein ziemlich großes Projekt mit vielen Adaptern, asynchronen Operationen mit Views und so weiter. Ein Entwickler entschied sich, set/getTag in seinem Teil des Codes zu verwenden, aber ein anderer hatte dieser Ansicht bereits ein Tag zugewiesen. Am Ende konnte jemand sein eigenes Etikett nicht finden und war sehr verwirrt. Das hat uns mehrere Stunden gekostet, um den Bug zu finden.

setTag(int key, Object tag) sieht viel besser aus, da Sie eindeutige Schlüssel für jedes Tag generieren können (mit id resources ), aber es gibt eine signifikante Einschränkung für Android <4.0. Aus Lint-Dokumenten:

Vor Android 4.0 wurden die Objekte bei der Implementierung von View.setTag (int, Object) in einer statischen Zuordnung gespeichert, in der die Werte stark referenziert wurden. Dies bedeutet, dass, wenn das Objekt Referenzen enthält, die auf den Kontext verweisen, der Kontext (der auf so ziemlich alles andere verweist) verloren geht. Wenn Sie eine Ansicht übergeben, enthält die Ansicht einen Verweis auf den Kontext, in dem sie erstellt wurde. In ähnlicher Weise enthalten Ansichtsinhaber normalerweise eine Ansicht und Cursor werden manchmal auch Ansichten zugeordnet.

117
Andrei Buneyeu

Wir können setTag() und getTag() verwenden, um benutzerdefinierte Objekte gemäß unseren Anforderungen festzulegen und abzurufen. Die Methode setTag() akzeptiert ein Argument vom Typ Object, und getTag() gibt ein Object zurück.

Zum Beispiel,

Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);
25
Ramkailash

Für Webentwickler scheint dies das Äquivalent zu data- ..

19
Oren

Dies ist sehr nützlich für die benutzerdefinierte ArrayAdapter Verwendung. Es ist eine Art Optimierung. Dort setTag wird anstelle von ListView als Referenz auf ein Objekt verwendet, das auf einige Teile des Layouts verweist (das in findViewById angezeigt wird).

static class ViewHolder {
    TextView tvPost;
    TextView tvDate;
    ImageView thumb;
}

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

    if (convertView == null) {
        LayoutInflater inflater = myContext.getLayoutInflater();
        convertView = inflater.inflate(R.layout.postitem, null);

        ViewHolder vh = new ViewHolder();
        vh.tvPost = (TextView)convertView.findViewById(R.id.postTitleLabel);
        vh.tvDate = (TextView)convertView.findViewById(R.id.postDateLabel);
        vh.thumb = (ImageView)convertView.findViewById(R.id.postThumb);
        convertView.setTag(vh);
    }
            ....................
}
14
shubniggurath

Im Gegensatz zu IDs werden Tags nicht zum Identifizieren von Ansichten verwendet. Tags sind im Wesentlichen zusätzliche Informationen, die einer Ansicht zugeordnet werden können. Sie werden am häufigsten verwendet, um Daten in Bezug auf Ansichten in den Ansichten selbst zu speichern, anstatt sie in einer separaten Struktur abzulegen.

Referenz: http://developer.Android.com/reference/Android/view/View.html

12
Saad Bilal

Das Setzen von TAGs ist sehr nützlich, wenn Sie eine ListView haben und die Ansichten wiederverwenden möchten. Auf diese Weise wird die ListView der neueren RecyclerView sehr ähnlich.

@Override
public View getView(int position, View convertView, ViewGroup parent)
  {
ViewHolder holder = null;

if ( convertView == null )
{
    /* There is no view at this position, we create a new one. 
       In this case by inflating an xml layout */
    convertView = mInflater.inflate(R.layout.listview_item, null);  
    holder = new ViewHolder();
    holder.toggleOk = (ToggleButton) convertView.findViewById( R.id.togOk );
    convertView.setTag (holder);
}
else
{
    /* We recycle a View that already exists */
    holder = (ViewHolder) convertView.getTag ();
}

// Once we have a reference to the View we are returning, we set its values.

// Here is where you should set the ToggleButton value for this item!!!

holder.toggleOk.setChecked( mToggles.get( position ) );

return convertView;
}
10
user5053330