Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

안드로이드 앱 만들기 list view 에 checkbox 넣어보기

Billcorea 2021. 8. 29. 14:48
반응형

앱을 만들다 보면 listview 혹인 recyclelistview 등을 사용할 일이 있다.  그런데, 그 안에 있는 item 으로 checkbox, button 등을 넣어 화면을 구성해 보면 (focus 가 도달하는 것들) listview 의 item click 이 제어되지 않고 그 안에 있는 checkbox나 button 등이 클릭 되는 현상을 보인다.

 이럴 떄 어떻게 하면 listview 의 item 으로 제어를 옮길 수 있는 것인가에 대한 고민이 생긴다.

구글신에게 물어보고 찾아보는 방법이 있기는 하지만, 그럴 시간이면 간단하게...

 

        <CheckBox
            android:id="@+id/ckSendSeqNo"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="8"
            android:focusable="false"
            android:clickable="false" />

 

checkbox 나 button 에게 focus가 가지 못하게 false 처리를 해 주는 것이다. click 도 못하게 false 을 해 준다.

그리고 listview 의 setOnItemClickListener 을 이용해서 

데이터 값을 조정해 주고 adapter 에서 checkbox 의 값을 설정해 주는 방식으로 처리를 해본다.

 

 

 

 

반응형
        binding.listSendMessage.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                int iCnt = 0 ;
                for(int i=0; i < beans.size() ;  i++) {
                    if (beans.get(i).isSelectedMsg()) iCnt++;
                }
                if (iCnt > 0) {
                    beans.get(position).setSelectedMsg(false);
                    adapter.notifyDataSetChanged(beans);
                    Toast.makeText(getContext(), iCnt +"개 이상 선택할 수 없습니다.", Toast.LENGTH_SHORT).show();
                    return;
                }
                beans.get(position).setSelectedMsg(!beans.get(position).isSelectedMsg());
                adapter.notifyDataSetChanged(beans);
            }
        });

beans.get(position).setSelectedMsg(false); 이렇게 false 로 하던지 아니면 true 로 설정을 한 다음...

import android.content.Context;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;

import com.example.smssend0823.R;
import com.example.smssend0823.databinding.DataitemBinding;

import java.util.ArrayList;

public class MsgSendAdapter extends BaseAdapter {

    DataitemBinding binding ;
    ArrayList<MsgTargetBean> msgTargetBeans ;
    LayoutInflater inflater;
    Context context ;
    int nListCnt ;

    public MsgSendAdapter(ArrayList<MsgTargetBean> odata, Context context) {
        this.msgTargetBeans = odata ;
        this.context = context ;
        this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

    @Override
    public Object getItem(int position) {
        return msgTargetBeans.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public void notifyDataSetChanged(ArrayList<MsgTargetBean> odata) {
        this.msgTargetBeans = odata ;
        nListCnt = msgTargetBeans.size();
        this.notifyDataSetChanged();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        binding = DataitemBinding.inflate(inflater);
        CustomViewHolder holder ;
        if (convertView == null) {
            convertView = binding.getRoot() ;
            holder = new CustomViewHolder();
            holder.ckSendSeqNo = binding.ckSendSeqNo ;
            holder.txtSendMessage = binding.txtSendMessage ;
            holder.txtReceivedPhoneNum = binding.txtReceivedPhoneNum ;
            holder.txtSendTy = binding.txtSendTy ;
            convertView.setTag(holder);
        } else {
            holder = (CustomViewHolder) convertView.getTag();
        }

        holder.ckSendSeqNo.setChecked(msgTargetBeans.get(position).getSelectSend());
        holder.ckSendSeqNo.setText(msgTargetBeans.get(position).getSendSeqNo());
        holder.txtSendMessage.setText(msgTargetBeans.get(position).getSendMessage());
        holder.txtReceivedPhoneNum.setText(msgTargetBeans.get(position).getReceivePhoneNum());
        if ("Y".equals(msgTargetBeans.get(position).getSendTy())) {
            holder.txtSendTy.setText("전송완료");
            holder.txtSendTy.setBackgroundColor(context.getColor(R.color.softBlue));
            holder.txtSendTy.setTextColor(context.getColor(R.color.white));
        } else {
            holder.txtSendTy.setText("");
            holder.txtSendTy.setBackgroundColor(context.getColor(R.color.white));
            holder.txtSendTy.setTextColor(context.getColor(R.color.white));
        }
        return convertView;
    }

    public class CustomViewHolder {
        CheckBox ckSendSeqNo ;
        TextView txtSendTy ;
        TextView txtSendMessage ;
        TextView txtReceivedPhoneNum ;
    }
}

holder.ckSendSeqNo.setChecked(msgTargetBeans.get(position).getSelectSend()); 처럼 실행해 주면 그것으로 끝.

adapter 을 호출하는 전체 소스는 아래와 같다.

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;

import com.example.smssend0823.Database.DBHandler;
import com.example.smssend0823.Database.MsgTargetBean;
import com.example.smssend0823.Database.SendMessageAdapter;
import com.example.smssend0823.Database.SendMessageBean;
import com.example.smssend0823.Utils.OnBackPressedListener;
import com.example.smssend0823.databinding.FragmentMsgselectBinding;

import java.util.ArrayList;

public class MsgSelectFragment extends Fragment implements OnBackPressedListener {

    private static final String TAG = "MsgSelectFragment";
    private FragmentMsgselectBinding binding;
    ArrayList<SendMessageBean> beans;
    SendMessageAdapter adapter;
    DBHandler dbHandler ;
    String phoneNo ;
    String message ;
    private static final int PERMISSION_RQST_SEND = 101;

    public static Fragment newInstance() {
        MsgSelectFragment fragment = new MsgSelectFragment();
        return fragment;
    }

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {

        binding = FragmentMsgselectBinding.inflate(inflater, container, false);
        return binding.getRoot();

    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        beans = new ArrayList<>();
        doDisplaySendMessage();
        binding.listSendMessage.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                int iCnt = 0 ;
                for(int i=0; i < beans.size() ;  i++) {
                    if (beans.get(i).isSelectedMsg()) iCnt++;
                }
                if (iCnt > 0) {
                    beans.get(position).setSelectedMsg(false);
                    adapter.notifyDataSetChanged(beans);
                    Toast.makeText(getContext(), iCnt +"개 이상 선택할 수 없습니다.", Toast.LENGTH_SHORT).show();
                    return;
                }
                beans.get(position).setSelectedMsg(!beans.get(position).isSelectedMsg());
                adapter.notifyDataSetChanged(beans);
            }
        });

        binding.btnSendMessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = 0 ; int iCnt = 0 ;
                for(int i=0; i < beans.size() ;  i++) {
                    if (beans.get(i).isSelectedMsg()) {
                        position = i;
                        iCnt++;
                        break;
                    };
                }
                if (iCnt == 0) {
                    Toast.makeText(getContext(), "전송할 메시지를 선택하세요.", Toast.LENGTH_SHORT).show();
                    return;
                }
                message = beans.get(position).getSendMessage() ;
                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("메시지 전송")
                        .setMessage("[" + beans.get(position).getSendMessage() + "] 로 전송할까요?")
                        .setPositiveButton("확인", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dbHandler = DBHandler.open(getContext());
                                Cursor rs = dbHandler.selectAll();
                                while(rs.moveToNext()) {
                                    MsgTargetBean msgTargetBean = new MsgTargetBean();
                                    msgTargetBean.setId(rs.getInt(rs.getColumnIndex("_id")));
                                    msgTargetBean.setSendSeqNo(rs.getString(rs.getColumnIndex("sendSeqNo")));
                                    msgTargetBean.setReceivePhoneNum(rs.getString(rs.getColumnIndex("receivePhoneNum")));
                                    msgTargetBean.setSendMessage(rs.getString(rs.getColumnIndex("sendMessage")));
                                    msgTargetBean.setSendTy(rs.getString(rs.getColumnIndex("sendTy")));
                                    if("S".equals(msgTargetBean.getSendTy())) {
                                        phoneNo = msgTargetBean.getReceivePhoneNum();
                                        if (sendSMSMessage()) {
                                            msgTargetBean.setSendTy("Y");
                                            msgTargetBean.setSendMessage(message);
                                            dbHandler.update(msgTargetBean);
                                        }
                                    }
                                }
                                dbHandler.close();
                            }
                        })
                        .setNegativeButton("취소", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        });
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        });
    }

    private void doDisplaySendMessage() {
        beans.clear();
        dbHandler = DBHandler.open(getContext());
        Cursor rs = dbHandler.selectMsgAll();
        while (rs.moveToNext()) {
            SendMessageBean bean = new SendMessageBean();
            bean.setSendMessage(rs.getString(rs.getColumnIndex("messageString")));
            beans.add(bean);
        }
        adapter = new SendMessageAdapter(beans, getContext());
        adapter.notifyDataSetChanged(beans);
        binding.listSendMessage.setAdapter(adapter);
    }

    protected boolean sendSMSMessage() {
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(getContext(), "SMS 전송 권한에 대한 허가가 필요합니다.", Toast.LENGTH_SHORT).show();
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),Manifest.permission.SEND_SMS)) {
                Log.e(TAG, "shouldShowRequestPermissionRationale");
            }
            else { ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.SEND_SMS}, PERMISSION_RQST_SEND);
                Log.e(TAG, "requestPermissions");
            }
        } else {
            SmsManager smsManager = SmsManager.getDefault();
            smsManager.sendTextMessage(phoneNo, null, message, null, null);
            Toast.makeText(getContext(), "메시지가 전송 되었습니다.",Toast.LENGTH_LONG).show();
            return true ;
        }
        return false;
    }
    //Now once the permission is there or not would be checked
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_RQST_SEND: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                } else {Toast.makeText(getContext(), "SMS 발송이 되지 않았습니다. 잠시 뒤에 다시 시도 하세요.", Toast.LENGTH_LONG).show();
                    return;
                }
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    @Override
    public void onBackPressed() {
        getParentFragmentManager().beginTransaction()
                .replace(R.id.container, MsgSendListFragment.newInstance())
                .commitNow();
    }
}

 

그럼 오늘도 즐~ 코딩...

반응형