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

recyclerview 사용할 때 debug로 올렸을 때 되던게 release로 올리면 문제가 발생합니다. [closed]

0 추천
 

안녕하세요 안드로이드 초보개발자입니다.

recyclerview를 사용하던 중 의문점이 발생해서 이렇게 글 남깁니다.

debug로 올린 앱에서는 문제없이 작동하는데 release로 올리게 되면

header view가 안보이고 item들이 중복되서 나타나는 현상을 겪고 있습니다.

혹시 비슷한 경험을 하셨거나 해결 방안을 아시는 분은 조언 부탁드립니다. ㅠㅠ

아래 코드는 adapter 부분 코드입니다.

public ThermometerScanAdapter(Context context, Class<? extends RecyclerView.ViewHolder> clazz,
                                  List<BluetoothDevice> data, Map<String, Integer> rssiMap){
        this.mLayoutInflator = LayoutInflater.from(context);
        this.mBodyHolderClazz = clazz;
        this.mData = data;
        this.mRssiMap = rssiMap;

        this._HEADER_ENABLE = BuildConfig.DEBUG ? 1 : 0;
        this._EMPTY_ENABLE = 1;

        cSignalFine = ActivityCompat.getColor(context, R.color.scanSignalFine);
        cSignalPoor = ActivityCompat.getColor(context, R.color.scanSignalPoor);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == VIEW_TYPE_BODY){
            if(ThermometerScanHolder.class.equals(mBodyHolderClazz)){
                View v = mLayoutInflator.inflate(ThermometerScanHolder.LAYOUT_RES, parent, false);
                return new ThermometerScanHolder(v);
            }
            else if(ScannerScanHolder.class.equals(mBodyHolderClazz)){
                View v = mLayoutInflator.inflate(ScannerScanHolder.LAYOUT_RESOURCE, parent, false);
                return new ScannerScanHolder(v);
            }
        }
        else if(viewType == VIEW_TYPE_HEADER){
            View v = mLayoutInflator.inflate(ScanHeaderHolder.LAYOUT_RES, parent, false);
            return new ScanHeaderHolder(v);
        }
        else if(viewType == VIEW_TYPE_EMPTY){
            View v = mLayoutInflator.inflate(ScanEmptyHolder.LAYOUT_RES, parent, false);
            return new ScanEmptyHolder(v);
        }

        throw new IllegalArgumentException("Not accepted view type.");
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if(holder instanceof ThermometerScanHolder){
            bindViewHolder((ThermometerScanHolder) holder, position);
        }
        else if(holder instanceof ScannerScanHolder){
            bindViewScannerHolder((ScannerScanHolder) holder, position);
        }
        else if(holder instanceof ScanHeaderHolder){
            bindHeaderHolder((ScanHeaderHolder) holder);
        }
        else if(holder instanceof ScanEmptyHolder){
            bindEmptyHolder((ScanEmptyHolder) holder);
        }
    }

    /**
     * 검색된 디바이스 중 1개 가져오기
     * @param position
     * @return BluetoothDevice
     */
    public BluetoothDevice getItem(int position){
        return mData.get(getItemArrayPosition(position));
    }

    /**
     * Enable 된 Header (HeaderHolder, EmptyHolder)를 제외한 position을 계산
     * @param position  Adapter Position
     * @return Body Item Position
     */
    public int getItemArrayPosition(int position){
        return position - getActiveHeaderCount();
    }

    /** @deprecated
     * Enable 된 Header (HeaderHolder, EmptyHolder)를 포함하여 position을 계산
     * @param position Body Item Position
     * @return Adapter Position
     */
    public int getItemAdapterPosition(int position){
        return position + getActiveHeaderCount();
    }

    private void bindViewHolder(ThermometerScanHolder holder, int position){
        BluetoothDevice device = getItem(position);

        final String deviceAddress = device.getAddress();


        int rssiPrimitive = 0;

        if(mRssiMap.containsKey(deviceAddress)){
            Integer rssi = mRssiMap.get(deviceAddress);
            if(rssi != null) rssiPrimitive = rssi;
        }

        if(rssiPrimitive < 0){

            holder.thImage.setColorFilter(calRssiColor(rssiPrimitive));
        }

        holder.nameView.setText(device.getName());
        holder.addressView.setText(deviceAddress);
        holder.rssiView.setText(String.valueOf(rssiPrimitive));
    }

    private void bindViewScannerHolder(ScannerScanHolder holder, int position){
        BluetoothDevice device = getItem(position);

        holder.nameView.setText(device.getName());
        holder.addressView.setText(device.getAddress());
    }

    private void bindHeaderHolder(ScanHeaderHolder holder){

    }

    private void bindEmptyHolder(ScanEmptyHolder holder){

    }

    /**
     * RSSI에 따라 컬러값 계산
     * 최고로 안좋은 신호를 -105, 최고로 좋은 신호를 -35라고 지정됨.
     * @param rssiPrimitive rssi
     * @return Color값
     */
    private int calRssiColor(int rssiPrimitive){
        final int min = -105;
        final int max = -35;

        final float minmin = min / -127f;
        final float maxmax = max / -127f;


        int redFine = (cSignalFine >> 16) & 0xFF;
        int greenFine = (cSignalFine >> 8) & 0xFF;
        int blueFine = cSignalFine & 0xFF;

        int redPoor = (cSignalPoor >> 16) & 0xFF;
        int greenPoor = (cSignalPoor >> 8) & 0xFF;
        int bluePoor = cSignalPoor & 0xFF;

        //float ratio = rssiPrimitive / -127f;
        float ratio = (rssiPrimitive - max) / (float) min;

        if(ratio > 1f){
            ratio = 1f;
        }
        else if(ratio < 0f){
            ratio = 0;
        }

        int red = (int) (redFine - ((redFine - redPoor) * ratio));
        int green = (int) (greenFine - ((greenFine - greenPoor) * ratio));
        int blue = (int) (blueFine - ((blueFine - bluePoor) * ratio));


        return Color.argb(255, red, green, blue);
    }

    public void setScanState(boolean state){
        this.mScanState = state;
    }

    /**
     * 현재 Scan 상태를 알림, 검색 결과에 따라 View 그림
     *
     * @param state Scan 진행 상태
     */
    public void notifyScanState(boolean state){
        int enabled = getEnabledHeaderCount();
        mScanState = state;
        if(enabled > 0){
            int itemViewType = getItemViewType(0);
            if(state){
                if(mData.isEmpty() || itemViewType == VIEW_TYPE_BODY){//mData.isEmpty() &&
                    notifyItemInserted(0);
                }
                else{
                    notifyItemChanged(0);
                }
            }
            else{
                if(itemViewType == VIEW_TYPE_BODY){
                    notifyItemRemoved(0);
                }
                else{
                    notifyItemChanged(0);
                }
            }
        }
    }

    /**
     * Enable 된 Header 갯수
     * @return Header 갯수
     */
    private int getEnabledHeaderCount(){
        return _HEADER_ENABLE + _EMPTY_ENABLE;
    }

    /**
     * 활성화 된 Header 갯수
     * @return Header 갯수
     */
    private int getActiveHeaderCount() {
        if(hasCanVisibleHeader()){
            return _HEADER_ENABLE;
        }
        else if(hasCanVisibleEmpty()){
            return _EMPTY_ENABLE;
        }
        return 0;
    }


    @Override
    public int getItemCount() {
        return mData.size() + getActiveHeaderCount();
    }

    @Override
    public int getItemViewType(int position) {
        if(hasCanVisibleHeader() && position == 0){
            return VIEW_TYPE_HEADER;
        }
        else if(hasCanVisibleEmpty() && position == 0){
            return VIEW_TYPE_EMPTY;
        }
        return VIEW_TYPE_BODY;
    }

    /**
     * HedaerHolder가 지금 보일 수 있는 상황인지 체크
     * @return true면 보이는 상태
     */
    private boolean hasCanVisibleHeader(){
        return _HEADER_ENABLE == 1 && mScanState;
    }

    /**
     * EmptyHolder가 지금 보일수 있는 상황인지 체크
     * @return true면 보이는 상태
     */
    private boolean hasCanVisibleEmpty(){
        return _EMPTY_ENABLE == 1 && !mScanState && mData.isEmpty();
    }
질문을 종료한 이유: 해결하였습니다.
기철 (120 포인트) 님이 2020년 4월 1일 질문
기철님이 2020년 4월 1일 closed
...