addChild() для расширения макета объекта внутри элемента Listview, работая, но не показывая ребенка

Я пытаюсь сделать приложение, которое отображает ListView с пользовательским адаптером, где каждый элемент этого списка содержит объект трека класса, который расширяет RelativeView.

Приложение позволяет пользователю перетащить TextViews над ListView. Затем он вычисляет положение элемента ListView под перетаскиваемым ImageView, а затем добавляет Этот ImageView к RelativeLayout объекта track.

Проблема заключается в том, что после перетаскивания элемента по объекту Track элемента listView, TextView добавляется к RelativeView этого объекта, но он никогда не отображается. С помощью отладчика я проверил, что объект track действительно имеет ожидаемого ребенка.

What i’m doing wrong here, should I update some The RelativeLayouts afterwards?

Чтобы сделать это проще, Я заменил код для перетаскивания TextView в макете, и я просто поставил кнопку, которая при нажатии добавляет текстовое представление к дорожке в позиции 0 ListView.

Причина использования этого ListView для этого заключается в том, что я хочу, чтобы этот список был прокручиваемым. Является ли это правильным приближением или лучше использовать LinearLayout, содержащий объекты трека, внутри прокручиваемого контейнера?

Большое спасибо

Класс Трека

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

}

Пока здесь жеребьевка.трек отображается в каждом элементе ListView.

адаптер:

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

1 ответ

  1. Наконец я нашел решение. Проблема была на пути ссылки на объект трека класса, я хотел разместить представление. Линия

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

    were indeed doing nothing as the first received track was afterwarded by the content of the generic layout R. id.посмотреть.
    Я нашел этот хороший кусок кода здесь, который извлекает представление элемента в определенной позиции в ListView.

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

    Тогда путь в моем случае:

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

    Тогда все работает как положено.