0

Ich versuche, eine App, die eine ListView mit einem benutzerdefinierten Adapter zeigt, wo jedes Element dieser Liste ein Objekt der Klasse Track enthält, was RelativeView erweitert.addChild() zu Objekt Erweiterung Layout in Listview Element, funktioniert aber zeigt nicht das Kind

Die App ermöglicht es Benutzern, TextViews über die ListView zu ziehen. Dann berechnet es die Position des Elements der ListView unter der gezogenen ImageView und fügt dann diese ImageView der RelativeLayout des Track-Objekts hinzu.

Das Problem, das ich habe, ist, dass nach dem Ziehen des Objekts über das Track-Objekt des Elements listView die TextView der RelativeView dieses Objekts hinzugefügt wird, aber es wird nie angezeigt. Mit dem Debugger habe ich überprüft, dass das Track-Objekt tatsächlich das erwartete Kind hat.

Was mache ich hier falsch, sollte ich die RelativeLayouts danach irgendwie aktualisieren?

Um es einfacher zu machen, habe ich den Code für das Ziehen der TextView im Layout ersetzt, und ich einfach eine Schaltfläche, die beim Klicken fügt eine Textansicht der Spur in der Position 0 der ListView.

Der Grund für die Verwendung dieser ListView ist, weil ich diese Liste scrollbar haben möchte. Ist das eine richtige Annäherung, oder sollte ich besser ein LinearLayout mit den Track-Objekten in einem scrollbaren Container verwenden?

Vielen Dank

Die Track-Klasse

public class Track extends RelativeLayout { 

static public ArrayList<Track> trackList = new ArrayList<>(); 
public ArrayList<Light> lightsOnThisTrackList = new ArrayList<>(); 

Context context; 
private String name; 

LayoutInflater mInflater; 

public Track(Context _context) { 
    super(_context); 
    context = _context; 
    mInflater = LayoutInflater.from(_context); 
    init(); 

} 
public Track(Context _context, AttributeSet attrs, int defStyle) 
{ 
    super(_context, attrs, defStyle); 
    context = _context; 

    mInflater = LayoutInflater.from(_context); 
    init(); 
} 
public Track(Context _context, AttributeSet attrs) { 
    super(_context, attrs); 
    context = _context; 

    mInflater = LayoutInflater.from(_context); 
    init(); 
} 

public void init() { 

    mInflater.inflate(R.layout.track_view, this, true); 

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
    this.setLayoutParams(params); 

    final Track thisTrack = this; 
    this.context = context; 

    ImageView trackView = new ImageView(context); 
    trackView.setImageResource(R.drawable.track); 
    this.addView(trackView); 
} 

public void setName(String name) { 
    this.name = name; 
} 

public String getName() { 
    return name; 
} 

}

Bis hier ist der drawable.track in jedem Punkt des Listview zeigt.

Der Adapter:

public class TrackListAdapter extends ArrayAdapter<Track> { 

private static final String TAG = "TrackListAdapter"; 
private LayoutInflater layoutInflater; 
ArrayList<Track> trackArrayList; 
Context mContext; 


public TrackListAdapter(Context context, int textViewResourceId, ArrayList<Track> _trackArrayList) { 
    super(context, 0, _trackArrayList); 

    layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    this.mContext = context; 
    this.trackArrayList = _trackArrayList; 
} 

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

    if (convertView == null) { 
     convertView = layoutInflater.inflate(R.layout.track_list_item, null); 
    } 

    if (trackArrayList.size() != 0) { 
     Track track = trackArrayList.get(position); 
     TextView text = (TextView) convertView.findViewById(R.id.textView); 
     text.setText(track.getName()); //This is working and gets updated 

    } 

    return convertView; 
} 

}

public class MainActivity extends AppCompatActivity { 

private static final String TAG = "MainActivity"; 
RelativeLayout relativeLayout; 

Context context; 

ImageButton newItemButton ; 
Button button; 

public ListView trackListView; 
TrackListAdapter trackListAdapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    context = getApplicationContext(); 

    relativeLayout = (RelativeLayout) findViewById(R.id.mainLayout); 

    trackListView = (ListView) findViewById(R.id.trackListView); 
    trackListAdapter = new TrackListAdapter(this, 0, Track.trackList); 

    trackListView.setAdapter(trackListAdapter); 

    //This button adds new track to the list 

    button = (Button) findViewById(R.id.button); 
    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      Track.trackList.add(new Track(context)); 
      Log.i(TAG, "onClick " + Track.trackList.size()); 
      trackListAdapter.notifyDataSetChanged(); 
     } 
    }); 

    //This button adds a new TextView to the track object of the item(0) 
    //of the ListView. The view is added, according to the debugger, 
    //but it is not shown 

    newItemButton = (ImageButton) findViewById(R.id.newItemButton); 

    newItemButton .setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 

      Track track = trackListAdapter.getItem(0); 
      track = (Track) findViewById(R.id.view); 

      RelativeLayout.LayoutParams imParams = 
        new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 

      TextView text = new TextView(context); 
      text.setText("hello world!"); 

      track.addView(text, imParams); 
      trackListAdapter.notifyDataSetChanged(); 

      return false; 
     } 
    }); 

} 

Track_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
</RelativeLayout> 

track_list_item.xml

<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 


    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="?android:attr/textAppearanceLarge" 
     android:text="Large Text" 
     android:id="@+id/textView" /> 

    <com.example.microinnova.smartcontrol.Track 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/view" /> 

</LinearLayout> 
+0

Aus dem Blick auf Ihren Code, gibt es keinen Ort, wo Sie tatsächlich die zugrunde liegenden Daten Ihres Adapters ändern - so hat 'trackListAdapter.notifyDataSetChanged()' hat keinen Effekt. Sie müssen eine Methode in Ihrem Adapter hinzufügen, die eine 'Spur' hinzufügt (zur' ArrayList trackArrayList '). Fügen Sie eine Methode wie 'public void addItem (Track-Element) {trackArrayList.add (item); } ' – ishmaelMakitla

+0

Es gibt die Zeile' Track.trackList.add (neuer Track (Kontext)) 'und' Track.trackList' ist an den Adapter in der Zeile 'new TrackListAdapter (this, 0, Track.trackList)' gebunden. Ich glaube nicht, dass das das Problem ist, da die listView die neue Spur nach einem Klick auf den Button zeigt. Das Problem ist, dass beim Klicken auf "newItemButton", das eines der Track-Objekte ändern soll, das sich bereits in der Liste befindet, nichts visuell mit diesem Objekt passiert. – gotramaval

Antwort

0

Endlich fand ich die Lösung. Das Problem bestand darin, das Objekt der Klasse Track zu referenzieren, wo ich die Ansicht platzieren wollte. Die Linien

Track track = trackListAdapter.getItem(0); 
     track = (Track) findViewById(R.id.view); 

waren in der Tat nichts zu tun, als die erste abgerufene Spur danach durch den Inhalt des generischen Layout R.id.view ersetzt wurde. Ich fand dieses nette Stück Code here, der die Ansicht eines Artikels an einer bestimmten Position in einem ListView abruft.

public View getViewByPosition(int pos, ListView listView) { 
    final int firstListItemPosition = listView.getFirstVisiblePosition(); 
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1; 

    if (pos < firstListItemPosition || pos > lastListItemPosition) { 
     return listView.getAdapter().getView(pos, null, listView); 
    } else { 
     final int childIndex = pos - firstListItemPosition; 
     return listView.getChildAt(childIndex); 
    } 
} 

Dann wird die Art und Weise in meinem Fall zu gehen:

 View view = trackListAdapter.getViewByPosition(trackNumber, trackListView); 
     Track track = (Track) view.findViewById(R.id.view); 

     track.addView(viewToAdd); 

Dann ist alles wie erwartet funktioniert.