Android OnClickListener funktioniert auf LinearLayout nicht

derSoerrn

Aktives Mitglied
Guten Tag,

ich habe ein merkwürdiges Problem: Es gibt eine CustomView Klasse
Code:
extends LinearLayout
. Diese Klasse lädt ein XML-File mit zwei TextViews. Nun wollte ich, dass man auf meine CustomView-Klasse klicken kann, also setzte ich einen onClickListener. Dieser funktioniert allerdings nicht auf API Level 10 (Android 2.3.3), ab API-Level 16 jedoch schon. Kann mir jemand von Euch helfen?

Anbei die beiden Klassen, um die es geht:

Java:
package de.projektkurs.viewpager;

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class Drag extends LinearLayout implements DragSource, DropTarget{
	
	private Context c;
	@SuppressWarnings("unused")
	private AttributeSet as;
	@SuppressWarnings("unused")
	private int style;
	
	private String sTyp;
	private int apiLevel = android.os.Build.VERSION.SDK_INT;
	
	public long ID;
	
	private int iTyp;
	private int iRaum;
	private int iIndex;
	
	public boolean mEmpty;
	
	private TextView tvTyp, tvName;
	private View v;
	public ViewGroup vg;
	
	public Drag(Context context) {
		super(context);
		c = context;
		ladeObjekte();
	}
	
	public Drag(Context context, AttributeSet attrs) {
		super(context);
		c = context;
		as = attrs;
		ladeObjekte();
	}
	
	public Drag(Context context, AttributeSet attrs, int style) {
		super(context);
		c = context;
		as = attrs;
		this.style = style;
		ladeObjekte();
	}
	
	/**
	 * Es werden die TextViews des Objekts initalisiert
	 */
	private void ladeObjekte(){
		v = new View(c);
        LayoutInflater inflater = LayoutInflater.from(c);
        v = inflater.inflate(R.layout.gfx_objekte, null, false);
        this.addView(v);
		tvTyp = (TextView)v.findViewById(R.id.tvObjektTyp);
		tvName = (TextView)v.findViewById(R.id.tvObjektName);		
	}
	
	/**
	 * Legt die erste Textzeile des View-Objekts fest.
	 * @param raum
	 */
	@SuppressWarnings("deprecation")
	public void setzeRaum(int raum){
		switch (raum) {
		case Werte.M:
			if (apiLevel <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1){
		    	v.setBackgroundDrawable(c.getResources().getDrawable(R.drawable.matrix_object_selector));
		    } else{
		    	v.setBackground(c.getResources().getDrawable(R.drawable.matrix_object_selector));
		    }
			break;
		case Werte.R2:
			if (apiLevel <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1){
		    	v.setBackgroundDrawable(c.getResources().getDrawable(R.drawable.r2_object_selector));
		    } else{
		    	v.setBackground(c.getResources().getDrawable(R.drawable.r2_object_selector));
		    }
			break;
		case Werte.R3:
			if (apiLevel <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1){
		    	v.setBackgroundDrawable(c.getResources().getDrawable(R.drawable.r3_object_selector));
		    } else{
		    	v.setBackground(c.getResources().getDrawable(R.drawable.r3_object_selector));
		    }
			break;
			
		default:
			break;
		}
	}
	
	/**
	 * Legt den Typ des Objekts fest.
	 * @param typ
	 */
	public void setzeTyp(int typ){
		switch (typ) {
		case Werte.TYP_M:
			sTyp = "Matrix";
			break;
		case Werte.TYP_P2D:
			sTyp = "Punkt";
			break;
		case Werte.TYP_V2D:
			sTyp = "Vektor";
			break;
		case Werte.TYP_G2D:
			sTyp = "Gerade";
			break;
		case Werte.TYP_P3D:
			sTyp = "Punkt";
			break;
		case Werte.TYP_V3D:
			sTyp = "Vektor";
			break;
		case Werte.TYP_G3D:
			sTyp = "Gerade";
			break;
		case Werte.TYP_E3D:
			sTyp = "Ebene";
			break;
		default:
			sTyp = "Falscher Typ...";
			break;
		}
		tvTyp.setText(sTyp);
	}
	
	/**
	 * Legt den Namen des Objekts fest.
	 * @param name
	 */
	public void setzeName(String name){
		tvName.setText(name);
	}
	
	public void setzeID(long id){
		this.ID = id;
	}

	@Override
	public void getHitRect(Rect outRect) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void getLocationOnScreen(int[] loc) {
		// TODO Auto-generated method stub
		
	}
	
	//Für Drag'n'Drop Opperation benötigt:
	
	/**
	 * This method is called to determine if the DragSource has something to
	 * drag.
	 * 
	 * @return True if there is something to drag
	 */

	public boolean allowDrag() {
		// There is something to drag if the cell is not empty.
		return !mEmpty;
	}

	/**
	 * setDragController
	 * 
	 */

	public void setDragController(DragController dragger) {
		// Do nothing. We do not need to know the controller object.
	}

	/**
	 * onDropCompleted
	 * 
	 */

	public void onDropCompleted(View target, boolean success) {
		// If the drop succeeds, the image has moved elsewhere.
		// So clear the image cell.
		System.out.println(success+" = Success");
		if (success) {
			mEmpty = true;
			if (this.getId() >= 0) {
				int bg = mEmpty ? R.color.cell_empty : R.color.cell_filled;
				setBackgroundResource(bg);
				setBackgroundColor(color.transparent);
				Toast.makeText(c, "Hallo", Toast.LENGTH_SHORT).show();
			} else {
				// For convenience, we use a free-standing ImageCell to
				// take the image added when the Add Image button is clicked.
				Toast.makeText(c, "Hallo", Toast.LENGTH_SHORT).show();
			}
		}else{
			Toast.makeText(c, "Wuhuuuu es funktioniert :)))", Toast.LENGTH_SHORT).show();
		}
	}

	/**
 */
	// DropTarget interface implementation

	/**
	 * Handle an object being dropped on the DropTarget. This is the where the
	 * drawable of the dragged view gets copied into the ImageCell.
	 * 
	 * @param source
	 *            DragSource where the drag started
	 * @param x
	 *            X coordinate of the drop location
	 * @param y
	 *            Y coordinate of the drop location
	 * @param xOffset
	 *            Horizontal offset with the object being dragged where the
	 *            original touch happened
	 * @param yOffset
	 *            Vertical offset with the object being dragged where the
	 *            original touch happened
	 * @param dragView
	 *            The DragView that's being dragged around on screen.
	 * @param dragInfo
	 *            Data associated with the object being dragged
	 * 
	 */
	@SuppressLint("NewApi")
	@SuppressWarnings("deprecation")
	public void onDrop(DragSource source, int x, int y, int xOffset,
			int yOffset, DragView dragView, Object dragInfo) {
		// Mark the cell so it is no longer empty.
		mEmpty = false;
		int bg = mEmpty ? R.color.cell_empty : R.color.cell_filled;
		setBackgroundResource(bg);

		// The view being dragged does not actually change its parent and switch
		// over to the ImageCell.
		// What we do is copy the drawable from the source view.
		LinearLayout sourceView = (LinearLayout) source;
		Drawable d = sourceView.getBackground();
		if (d != null) {
			if(apiLevel < android.os.Build.VERSION_CODES.JELLY_BEAN){
				this.setBackgroundDrawable(d);
			}else{
				this.setBackground(d);
			}
		}

		// toast ("onDrop cell " + mCellNumber);

	}

	/**
	 * React to a dragged object entering the area of this DropSpot. Provide the
	 * user with some visual feedback.
	 */
	public void onDragEnter(DragSource source, int x, int y, int xOffset,
			int yOffset, DragView dragView, Object dragInfo) {
		int bg = mEmpty ? R.color.cell_empty_hover : R.color.cell_filled_hover;
		setBackgroundResource(bg);
	}

	/**
	 * React to something being dragged over the drop target.
	 */
	public void onDragOver(DragSource source, int x, int y, int xOffset,
			int yOffset, DragView dragView, Object dragInfo) {
	}

	/**
	 * React to a drag
	 */
	public void onDragExit(DragSource source, int x, int y, int xOffset,
			int yOffset, DragView dragView, Object dragInfo) {
		int bg = mEmpty ? R.color.cell_empty : R.color.cell_filled;
		setBackgroundResource(bg);
	}

	/**
	 * Check if a drop action can occur at, or near, the requested location.
	 * This may be called repeatedly during a drag, so any calls should return
	 * quickly.
	 * 
	 * @param source
	 *            DragSource where the drag started
	 * @param x
	 *            X coordinate of the drop location
	 * @param y
	 *            Y coordinate of the drop location
	 * @param xOffset
	 *            Horizontal offset with the object being dragged where the
	 *            original touch happened
	 * @param yOffset
	 *            Vertical offset with the object being dragged where the
	 *            original touch happened
	 * @param dragView
	 *            The DragView that's being dragged around on screen.
	 * @param dragInfo
	 *            Data associated with the object being dragged
	 * @return True if the drop will be accepted, false otherwise.
	 */
	public boolean acceptDrop(DragSource source, int x, int y, int xOffset,
			int yOffset, DragView dragView, Object dragInfo) {
		// An ImageCell accepts a drop if it is empty and if it is part of a
		// grid.
		// A free-standing ImageCell does not accept drops.
		return mEmpty && (this.getId() >= 0);
	}

	/**
	 * Estimate the surface area where this object would land if dropped at the
	 * given location.
	 * 
	 * @param source
	 *            DragSource where the drag started
	 * @param x
	 *            X coordinate of the drop location
	 * @param y
	 *            Y coordinate of the drop location
	 * @param xOffset
	 *            Horizontal offset with the object being dragged where the
	 *            original touch happened
	 * @param yOffset
	 *            Vertical offset with the object being dragged where the
	 *            original touch happened
	 * @param dragView
	 *            The DragView that's being dragged around on screen.
	 * @param dragInfo
	 *            Data associated with the object being dragged
	 * @param recycle
	 *            {@link Rect} object to be possibly recycled.
	 * @return Estimated area that would be occupied if object was dropped at
	 *         the given location. Should return null if no estimate is found,
	 *         or if this target doesn't provide estimations.
	 */
	public Rect estimateDropLocation(DragSource source, int x, int y,
			int xOffset, int yOffset, DragView dragView, Object dragInfo,
			Rect recycle) {
		return null;
	}

	/**
 */
	// Other Methods

	/**
	 * Return true if this cell is empty. If it is, it means that it will accept
	 * dropped views. It also means that there is nothing to drag.
	 * 
	 * @return boolean
	 */

	public boolean isEmpty() {
		return mEmpty;
	}

	/**
	 * Call this view's onClick listener. Return true if it was called. Clicks
	 * are ignored if the cell is empty.
	 * 
	 * @return boolean
	 */

	public boolean performClick() {
		if (!mEmpty)
			return super.performClick();
		return false;
	}

	/**
	 * Call this view's onLongClick listener. Return true if it was called.
	 * Clicks are ignored if the cell is empty.
	 * 
	 * @return boolean
	 */

	public boolean performLongClick() {
		if (!mEmpty)
			return super.performLongClick();
		return false;
	}
	
	

}

und

Java:
package de.projektkurs.viewpager;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import de.projektkurs.elementActivity1.ElementActivity1;
import de.projektkurs.tools.ObjectContainer;
import de.projektkurs.tools.Werte;

@SuppressLint("NewApi")
public class R2Adapter extends BaseAdapter implements OnLongClickListener{
	private Context c;
	private OnLongClickListener listener;
	
	private String sName;
	private int iTyp, iRaum;
	
	public R2Adapter(Context context){
		c = context;
	}
		
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return ObjectContainer.math2d.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return ObjectContainer.math2d.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		sName = ObjectContainer.math2d.get(position).gibName();
		iRaum = Werte.R2;
		iTyp = ObjectContainer.math2d.get(position).gibTyp();
		Drag d = null;
	    if (convertView == null) {
	        // Wenn noch kein DragObjekt existiert wird eins erstellt, 
	    	// sonst wird es geändert.
	        d = new Drag(c);
	        d.setLayoutParams(new GridView.LayoutParams(170, 140));
	        d.setzeName(sName);
	        d.setzeTyp(iTyp);
	        d.setzeRaum(iRaum);
	        d.setzeID(position);
	        System.out.println(sName+", "+iTyp+", "+iRaum);
	    } else {
	        d = (Drag) convertView;
	    }

	    d.setzeID(position);
	    d.vg = (GridView) parent;
	    
	    d.setClickable(true);
	    
	    d.setOnLongClickListener (listener);
	    
	    d.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				System.out.println("Wurde Geklickt");
			    Intent i = new Intent().setClass(c, ElementActivity1.class);
                i.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                
                Bundle b = new Bundle();
                b.putInt("room", Werte.R2);
                b.putInt("type", ObjectContainer.math2d.get(position).gibTyp());
                b.putInt("index0", position);
                b.putInt("count", 1);
                
                i.putExtras(b);

                // Activity starten
                c.startActivity(i);
			}
			
		});
	    
		return d;
	}

	@Override
	public boolean onLongClick(View v) {
		// TODO Auto-generated method stub
		return false;
	}
	
	/**
	 * Es wird ein LongClickListener gesetzt.
	 * @param l {@link OnLongClickListener}
	 */
	public void setzeLongClickListener(OnLongClickListener l){
		listener = l;
	}
}

BTW, der LongClickListener funktioniert ebenfalls nicht :/


Gruß
 
A

asdfghjl

Gast
Ziemlich viel Text...

Grundsätzlich funktionieren die OnClickListener auf LinearLayout auch unter API 10

Kannst Du mal abgespeckten Code liefern mit dem man das Phänomen nachvollziehen kann?
 

derSoerrn

Aktives Mitglied
Die CustomView Klasse (hat jetzt nur noch Methoden, um z.B. den Namen zu setzen)
Java:
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class Objekt extends LinearLayout {

	private Context c;
	private AttributeSet as;
	private int style;

	private String sTyp;
	private int apiLevel = android.os.Build.VERSION.SDK_INT;

	public long ID;

	private int iTyp;
	private int iRaum;
	private int iIndex;

	public boolean mEmpty;

	private TextView tvTyp, tvName;
	private View v;
	public ViewGroup vg;

	public Objekt(Context context) {
		super(context);
		c = context;
		ladeObjekte();
	}

	public Objekt(Context context, AttributeSet attrs) {
		super(context);
		c = context;
		as = attrs;
		ladeObjekte();
	}

	public Objekt(Context context, AttributeSet attrs, int style) {
		super(context);
		c = context;
		as = attrs;
		this.style = style;
		ladeObjekte();
	}

	/**
	 * Es werden die TextViews des Objekts initalisiert
	 */
	private void ladeObjekte() {
		v = new View(c);
		LayoutInflater inflater = LayoutInflater.from(c);
		v = inflater.inflate(R.layout.gfx_objekte, null, false);
		this.addView(v);
		tvTyp = (TextView) v.findViewById(R.id.tvObjektTyp);
		tvName = (TextView) v.findViewById(R.id.tvObjektName);
	}

	/**
	 * Legt die erste Textzeile des View-Objekts fest.
	 * 
	 * @param raum
	 */
	public void setzeRaum(int raum) {

		if (apiLevel <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
			v.setBackgroundDrawable(c.getResources().getDrawable(
					R.drawable.ic_launcher));
		} else {
			v.setBackground(c.getResources()
					.getDrawable(R.drawable.ic_launcher));
		}
		System.out.println(apiLevel);
		System.out
				.println(android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1);
	}

	/**
	 * Legt den Typ des Objekts fest.
	 * 
	 * @param typ
	 */
	public void setzeTyp(int typ) {
		// Abgespeckt, nur da, damit etwas im Feld stehen würde
		tvTyp.setText("Typ");
	}

	/**
	 * Legt den Namen des Objekts fest.
	 * 
	 * @param name
	 */
	public void setzeName(String name) {
		tvName.setText(name);
	}
	
	/**
	 * 
	 * @param id
	 */
	public void setzeID(long id) {
		this.ID = id;
	}

}

Die Adapter Klasse, welche die CustomView Objekte verwaltet

Java:
public class R2Adapter extends BaseAdapter implements OnLongClickListener{
	private Context c;
	private OnLongClickListener listener;
	
	private String sName;
	private int iTyp, iRaum;
	
	public R2Adapter(Context context){
		c = context;
	}
		
	@Override
	public int getCount() {
		// Gibt die Anzahl der Objekte wieder
		return ObjectContainer.math2d.size();
	}

	@Override
	public Object getItem(int position) {
		// Gibt das Objekte an der angegeben Stelle zurück
		return ObjectContainer.math2d.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		Drag d = null;
	    if (convertView == null) {
	        // Wenn noch kein DragObjekt existiert wird eins erstellt, 
	    	// sonst wird es geändert.
	        d = new Drag(c);
	        d.setLayoutParams(new GridView.LayoutParams(170, 140));
	    } else {
	        d = (Drag) convertView;
	    }

	    d.vg = (GridView) parent;
	    
	    d.setClickable(true);
	    
	    d.setOnLongClickListener (listener);
	    
	    d.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				System.out.println("Wurde Geklickt");
			}
		});
	    
		return d;
	}

	@Override
	public boolean onLongClick(View v) {
		// TODO Auto-generated method stub
		return false;
	}
	
	/**
	 * Es wird ein LongClickListener gesetzt.
	 * @param l {@link OnLongClickListener}
	 */
	public void setzeLongClickListener(OnLongClickListener l){
		listener = l;
	}
}

Vielleicht noch zur Erklärung: Es gibt ein Fragment, auf diesem liegt ein ViewPager mit 3 Seiten. Der R2Adapter (2. Klasse) füllt den Viewpager mit Objekten aus einer Liste.

Soll ich noch mehr Klassen hochladen bzw noch weiter "abspecken"?
 

schlingel

Gesperrter Benutzer
Ich würde sagen, da frisst ein Adapter am Weg von Activity über FragmentHost zu Fragment den Event. Häng überall mal einen Listener an der den Namen der verwendeten Komponente ausspuckt und schau was passiert.

Liest sich vielleicht stümperhaft aber was besseres fällt mir da jetzt nicht ein.
 

derSoerrn

Aktives Mitglied
Das verstehe ich leider nicht so ganz. Was soll ich denn für einen Listener benutzen und auf welche Komponenten soll ich diesen dann adden?
 

schlingel

Gesperrter Benutzer
Kurze Verständnisfrage: Warum setzt du für jedes Listen-Objekt einen ClickListener anstatt dass du einen onItemClickListener für die ganze Liste setzt?
 

derSoerrn

Aktives Mitglied
Weil ich blöd war :D ich habe es jetzt selbst so geschrieben, wie Du meintest. Mich würde aber trd interessieren, warum man mit API lvl. 16 auf die Objekte klicken konnte, mit 10 jedoch nicht. Weißt Du das?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Frage zu OnClickListener. Verständnisproblem Android & Cross-Platform Mobile Apps 5
W Wie kann man OnClicklistener und OnCheckedChangeListener zusammen ausführen Android & Cross-Platform Mobile Apps 18
S onClickListener auf Buttons die im Code erzeugt wurden setzen. Android & Cross-Platform Mobile Apps 8
MaxG. Android Absturz bei Aufruf von onClickListener() Android & Cross-Platform Mobile Apps 8
G OnCLICKListener - OnTOUCHListener Android & Cross-Platform Mobile Apps 2
L Bitmap mit OnClickListener Android & Cross-Platform Mobile Apps 8
H Android TranslateAnimation und OnClickListener Android & Cross-Platform Mobile Apps 2
M PythonInterpreter funktioniert nicht richtig NoClassDefFoundError Android & Cross-Platform Mobile Apps 1
W Wie funktioniert das mit den Fingerabdruck Login? (Meinung) Android & Cross-Platform Mobile Apps 13
Besset Android http request an interne ip adresse funktioniert nicht Android & Cross-Platform Mobile Apps 8
J App funktioniert auf Android 5, auf 6 nicht Android & Cross-Platform Mobile Apps 2
L Android Android Studio - Exportierte APK funktioniert nicht Android & Cross-Platform Mobile Apps 6
L Android Methode funktioniert nicht unter Android Android & Cross-Platform Mobile Apps 3
J android Spinner funktioniert nicht Android & Cross-Platform Mobile Apps 14
K MediaPlayer Soundklasse Start und Stop (stop funktioniert nicht) Android & Cross-Platform Mobile Apps 1
K Wie funktioniert die App Fatbooth? Wie viel Bildbearbeitung bringt Android mit? Android & Cross-Platform Mobile Apps 1
S SPLIT funktion bei STRING funktioniert nicht! Android & Cross-Platform Mobile Apps 4
J Android SimpleDateFormat parser funktioniert nicht richtig? Android & Cross-Platform Mobile Apps 4
B Erste Android-App: setContentView(R.layout.main) funktioniert nicht Android & Cross-Platform Mobile Apps 6
N Android EditText.setError() funktioniert nicht nach Rotation Android & Cross-Platform Mobile Apps 1
S Auflösungsanpassung funktioniert nicht Android & Cross-Platform Mobile Apps 2
E LayoutInflater funktioniert nicht Android & Cross-Platform Mobile Apps 2
A Fehler beim Starten eines Intents - alles in einer Klasse funktioniert... Android & Cross-Platform Mobile Apps 4
F Android: Socket.isConnected funktioniert nicht Android & Cross-Platform Mobile Apps 4
W Command funktioniert nicht Android & Cross-Platform Mobile Apps 5
X FileConnection - funktioniert bei mir nicht. Android & Cross-Platform Mobile Apps 7
J Image reinladen funktioniert nicht. Android & Cross-Platform Mobile Apps 13
JAVAnnik Click auf LinearLayout Android & Cross-Platform Mobile Apps 1
G Warnung bei: RelativeLayout / ScrollView / LinearLayout Android & Cross-Platform Mobile Apps 2

Ähnliche Java Themen

Neue Themen


Oben