마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

BaseAdpater에서 Listview 클릭시 intent로 다른 액티비티로 전환되면서 저장된 값도 불러오고 싶습니다.

0 추천

 

ListEAdapter는 BaseAdpater로 상속받아 사용합니다.

listview에 각각의 버튼을 클릭하면 EditActicity.class로 intent됩니다.

수정이므로 리스트뷰에 써져있는 TextView를 EditActivitiy에 있는 TextView에 setText를 해야하는데

여기를 어떻게 해야할지 모르겠습니다....Adapter에서 하는게 맞는가 싶기도 하고 

Activity에서 리스트뷰를 클릭해서 다른 Activity로 넘어가는게 실행이 안돼서 리스트뷰에 버튼을 추가해서 넘어간거라 Adpater에서 해결하고 싶습니다...

public class ListEAdapter extends BaseAdapter{

...
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
    {
        final int po = position;
        final Context context = parent.getContext();

      
       //오류납니다ㅜㅠㅜ EditActivity 에 있는 EditText 선언이 안돼요
       //EditText TitleET = (EditText) findViewById(R.id.TitleET);
       
     

        final ViewHolder holder;//아이템 내 view들을 저장할 holder 생성

        final Data item = listitem.get(position);


        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = inflater.inflate(R.layout.event_cell, parent, false);

            holder = new ViewHolder();

            .
            holder TitleTV = (TextView) convertView.findViewById(R.id.TitleTV);
            holder.DateTV = (TextView) convertView.findViewById(R.id.DateTV);

            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        holder.TitleTV.setText(item.getTitle());
        holder.DateTV.setText(item.getdate());
    
       // 리스트뷰의 수정버튼 클릭 -> EditActicity.class로 넘어감
      // 수정이므로 원래 저장된 EditText나 TextView를 가져와야하는데 이게 안됩니다.

        ImageButton EditBtn = (ImageButton) convertView.findViewById(R.id.EditBtn);
        EditBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            
                Intent intent = new Intent(v.getContext(), EditActivity.class);
                context.startActivity(intent);



            }
        });


        return convertView;
    }

 

 
------------------- 추가---------------------
ListAdapter.java
public class ListEAdapter extends BaseAdapter{

    public static ArrayList<Data> dataList = new ArrayList<>(); // 데이터목록

    ArrayList<Data> datas= new ArrayList<Data>();
    Context context;
    Activity activity;

    interface Listener{
        void onEdit(String title, String date);

    }
    private  Listener listener;
    public void setListener(Listener listener){
        this.listener = listener;
    }

    public ListAdapter(Context context, Activity activity, ArrayList<Data> datas)
    {
        this.context = context;
        this.activity = activity;
        this.datas= datas;
    }

    //뷰홀더 추가
    class ViewHolder {
        TextView TitleTV;
        TextView eventStartDateTV;

    }

    ...

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
    {
        final int po = position;
        final Context context = parent.getContext();

        final ViewHolder holder;//아이템 내 view들을 저장할 holder 생성

        final Data item = datas.get(position);

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = inflater.inflate(R.layout.item_cell, parent, false);

            holder = new ViewHolder();

            holder.TitleTV = (TextView) convertView.findViewById(R.id.TitleTV);
            holder.DateTV = (TextView) convertView.findViewById(R.id.DateTV);
      
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        holder.TitleTV.setText(event_item.getTitle());
        holder.DateTV.setText(event_item.getdate());
    
        ImageButton EditBtn = (ImageButton) convertView.findViewById(R.id.EditBtn);
        EditBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(v.getContext(), EditActivity.class);
                context.startActivity(intent);

               // 클릭한 리스트의 데이터
                String title = events.get(po).getTitle();
                String date = events.get(po).getdate();

                if(listener != null){

                    // 클릭한 리스트의 데이터
                    listener.onEdit(title, tdate);}
            }
        });

        return convertView;
    }


}

 

EditActivity.java

public class EditActivity extends AppCompatActivity implements Listener {

    private EditText TitleET;
    private TextView DateTV;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit);
        initWidgets();

        EditAction();
    }

    private void EditAction() {
    //해당 리스트 호출
     ArrayList<Data> datas= itemForDate(CalendarUtils.selectedDate);
        ListAdapter listAdapter = new ListAdapter(this, this, datas);
        listAdapter.setListener(new ListAdapter.Listener() {
            @Override
            public void onEdit(String title, String date) {
                TitleET.setText(title);
                DateTV.setText(date);

            }

        });

    }

    private void initWidgets()
    {
        TitleET = findViewById(R.id.TitleET);
        DateTV = findViewById(R.idtDateTV);

    }


}

 

andoror (150 포인트) 님이 2022년 6월 3일 질문
andoror님이 2022년 6월 3일 수정

3개의 답변

0 추천
 
채택된 답변

올리신 소소코드를 기반으로 동작하는 샘플코드를 만들어 봤습니다. 일부 클래스명, 변수명 등은 자바의 규칙에  맞는 좀 더 명료한 이름으로 변경했습니다.

import java.io.Serializable;

// Intent로 커스텀 오브젝트를 전달하려면 Serializable 또는 Parcelable을 구현해야 합니다.
public class EventItem implements Serializable {
    private final long id;
    private final String title;
    private final String date;

    public EventItem(long id, String title, String date) {
        this.id = id;
        this.title = title;
        this.date = date;
    }

    public long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public String getDate() {
        return date;
    }
}

 

public class EventAdapter extends BaseAdapter {

    private static class ViewHolder {
        TextView titleTv;
        TextView dateTv;
    }

    interface Listener {
       // 개별 필드를 전달할 필요없이 모든 필드가 들어있는 Serialzable 오브젝트를 하나 넘김.
        void onEdit(EventItem item);
    }

    private List<EventItem> items = new ArrayList<>();

    private Listener listener;

    public EventAdapter(List<EventItem> items) {
        this.items = items;
    }

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public EventItem getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return items.get(position).getId();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = createHolderView(parent);
        }

        final EventItem item = items.get(position);
        bindViewHolder(convertView, item);

        ImageButton editBtn = convertView.findViewById(R.id.editBtn);
        editBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) listener.onEdit(item);
            }
        });

        return convertView;
    }

    private void bindViewHolder(View convertView, EventItem item) {
        final ViewHolder holder = (ViewHolder) convertView.getTag();
        holder.titleTv.setText(item.getTitle());
        holder.dateTv.setText(item.getDate());
    }

    private View createHolderView(ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View itemView = inflater.inflate(R.layout.item_cell, parent, false);

        ViewHolder holder = new ViewHolder();
        holder.titleTv = itemView.findViewById(R.id.titleTv);
        holder.dateTv = itemView.findViewById(R.id.dateTv);
        itemView.setTag(holder);
        return itemView;
    }
}

 

public class EventActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);

        setupViews();
    }

    private void setupViews() {
        ListView eventListView = findViewById(R.id.eventList);
        EventAdapter eventAdapter = new EventAdapter(getEvents());
        eventAdapter.setListener(new EventAdapter.Listener() {
            @Override
            public void onEdit(EventItem item) {
                EventEditActivity.show(EventActivity.this, item);
            }
        });
        eventListView.setAdapter(eventAdapter);
    };

    // 테스트용 데이터이므로, 님의 코드를 사용하세요.
    private List<EventItem> getEvents() {
        return Arrays.asList(
                new EventItem(1, "Event1", "2022-06-01"),
                new EventItem(2, "Event2", "2022-06-02"),
                new EventItem(3, "Event3", "2022-06-03")
        );
    }
}

 

spark (226,420 포인트) 님이 2022년 6월 3일 답변
andoror님이 2022년 6월 3일 채택됨
0 추천

잘못된 건 아니지만 요즘은 ListView를 거의 사용하지 않습니다. RecyclerView를 대신 사용합니다. 그만큼 문제가 생기거나 하면 해결책 찾을 때 어려움도 있고, RecyclerView는 ListView보다는 최적화된 버전이라고 보시면 됩니다.

질문에 답을 하자면, 권장하는 접근방법은  ListView에서는 EditBtn 클리이벤트가 할당해 주고 내부의 동작은 외부로 위임하는 형태입니다. 왜냐하면 어댑터는 EditBtn을 누르는 이벤트는 알 수 있지만, 구체적으로 어떤 처리를 해야하는지는 어댑터의 몫이 아니기 때문입니다. 이렇게 할 경우 여러가지 이점이 있지만, 한가지 이유 중의 하나는 재사용성이 높아진다는 겁니다. 예를 들어 A, B화면에서 똑같은 어댑터를 사용해야 하는데 EditBtn에 대한 동작이 다르다고 가정할 경우, 현재와 같이 EditBtn의 OnClickListener의 코드가 어댑터에 존재할 경우는 재사용이 깔끔하지 않죠.

그러면, 수정 버튼을 눌렀을 때 이벤트의 내용을 밖으로 넘길 것이기 때문에 아래와 같이 호출하는 쪽과 어댑터를 연결할 인터페이스를 하나 만듧니다. 그리고 EditBtn이 눌리면 동작을 해당 인터페이스의 인스턴스에 넘깁니다.

public class ListEAdapter extends BaseAdapter{
    interface Listener {
          void onEdit();
    }

    private Listener listener;
    public void setListener(Listener listener) {
        this.listener = listener;
    }

...
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
    {
        ...
 
        editBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) listener.onEdit();
            }
        });
 
 
        ...
    }

 

이제 액티비티를 띄우는 코드는 호출하는 쪽에서 리스너를 통해 실행합니다.

ListEAdapter adapter = new ListEAdpater(); 
adapter.setListener(new ListEAdapter.Listener {
    @Override
     public void onEdit() {
        showEditActivity();
     }
});

private void showEditActivity() {
    Intent intent = new Intent(v.getContext(), EditActivity.class);
    context.startActivity(intent);
}

 

spark (226,420 포인트) 님이 2022년 6월 3일 답변
댓글 달아주신대로 구현했는데 클릭한 리스트의 TextView가 여전히 전달이 안돼요.. listener.onEdit(title, startdate, enddate, date, time); 으로 Activity에서 받도록 했는데 화면만 intent되고 데이터는 전달이 안되네요ㅜㅜ
작성하신 코드를 올리시면 시간 날 때 봐드릴게요.
수정한 부분 추가로 올렸습니다...! 정말 감사합니다. 조언해주신대로도 해봤고 interface 파일을 만들어서도 해봤는데도 intent만 되고 데이터는 전달이 안되더라구요...
0 추천
public class EventEditActivity extends AppCompatActivity {

    private static final String EXTRA_EVENT = "Event";

    public static void show(Context context, EventItem item) {
        Intent intent = new Intent(context, EventEditActivity.class);
        intent.putExtra(EXTRA_EVENT, item);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_edit);

        parseIntent();
    }

    private void parseIntent() {
        EditText titleEdit = findViewById(R.id.titleEdit);

        EventItem eventItem = (EventItem) getIntent().getSerializableExtra(EXTRA_EVENT);
        titleEdit.setText(eventItem.getTitle());

        EditText dateEdit = findViewById(R.id.dateEdit);
        dateEdit.setText(eventItem.getDate());
    }
}

 

spark (226,420 포인트) 님이 2022년 6월 3일 답변
...