使用ListView多Type的错误姿势

项目中,有这样的一个需求:

有三种打印机类型,每种类型可以添加、删除对应类型的打印机。
按照以往,我写的Adapter是这样的:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
public class  extends BaseAdapter {

    public final static int BLUETOOTH_HEADER = 0;    public final static int BLUETOOTH_PRINTER = 1;    public final static int NET_HEADER = 2;    public final static int NET_PRINTER = 3;    public final static int CLOUD_HEADER = 4;    public final static int CLOUD_PRINTER = 5;

    private Context mContext;    private LayoutInflater mInflater;    private OnItemFunctionClickListener listener;

    private List<PrinterInfo> mPrinters = new ArrayList<>();    private int blueToothCount = 0;    private int netCount = 0;    private int cloudCount = 0;

    public (Context context, List<PrinterInfo> printers, SwipePartMenuListView listView) {        mContext = context;        mPrinters = printers;        mInflater = LayoutInflater.from(context);

        getNotSwipeItem(listView);    }

    private void getNotSwipeItem(SwipePartMenuListView listView) {        blueToothCount = 0;        netCount = 0;        cloudCount = 0;

        for (PrinterInfo info : mPrinters) {            if (info.printerType == PrinterInfo.TYPE_BLUETOOTH) {                blueToothCount++;            } else if (info.printerType == PrinterInfo.TYPE_NETWORK) {                netCount++;            } else if (info.printerType == PrinterInfo.TYPE_CLOUD) {                cloudCount++;            }        }

        List<Integer> titleList = new LinkedList<>();        titleList.add(0);        titleList.add(1 + blueToothCount);        titleList.add(2 + blueToothCount + netCount);        listView.setCannotSwipePositionList(titleList);    }

    public void setPrinters(List<PrinterInfo> printers, SwipePartMenuListView listView) {        this.mPrinters = printers;

        getNotSwipeItem(listView);    }

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

    public View getView(int position, View convertView, ViewGroup parent) {        PrinterManagerViewHolder holder;        final int viewType = getItemViewType(position);        holder = new PrinterManagerViewHolder();        if (viewType == BLUETOOTH_HEADER || viewType == NET_HEADER || viewType == CLOUD_HEADER) {            if (convertView == null) {                convertView = mInflater.inflate(R.layout.item_printer_title, parent, false);                holder.headerTitle = (TextView) convertView.findViewById(R.id.printer_category_tv);                holder.headerIcon = (ImageView) convertView.findViewById(R.id.printer_icon_iv);                holder.headerAdd = (ImageView) convertView.findViewById(R.id.printer_add_device_iv);                holder.headerDivider = convertView.findViewById(R.id.printer_title_divider);                convertView.setTag(holder);            } else {                holder = (PrinterManagerViewHolder) convertView.getTag();            }        } else {            if (convertView == null) {                convertView = mInflater.inflate(R.layout.item_printer_devices, parent, false);                holder.connect = (TextView) convertView.findViewById(R.id.printer_connect_tv);                holder.divider = convertView.findViewById(R.id.printer_last_divider);                holder.setting = (TextView) convertView.findViewById(R.id.printer_setting_tv);                holder.title = (TextView) convertView.findViewById(R.id.printer_title_tv);                holder.connectIcon = (ImageView) convertView.findViewById(R.id.printer_connect_iv);                convertView.setTag(holder);            } else {                holder = (PrinterManagerViewHolder) convertView.getTag();            }        }        switch (viewType) {            case BLUETOOTH_HEADER:                holder.headerTitle.setText("蓝牙打印机");                holder.headerAdd.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.btn_setting_goods_add));                holder.headerAdd.setOnClickListener(new View.OnClickListener() {

                    public void onClick(View v) {                        BlueToothPrinterActivity.navigateTo(mContext);                    }                });                break;            case NET_HEADER:                holder.headerTitle.setText("网络打印机");                holder.headerAdd.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.btn_setting_goods_add));                holder.headerAdd.setOnClickListener(new View.OnClickListener() {

                    public void onClick(View v) {                        NetPrinterActivity.navigateTo(mContext);                    }                });                break;            case CLOUD_HEADER:                holder.headerTitle.setText("云打印机");                holder.headerAdd.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.btn_setting_goods_scan));                if (position == getCount() - 1) {                    holder.headerDivider.setVisibility(View.VISIBLE);                }                break;            case BLUETOOTH_PRINTER:                PrinterInfo printer = mPrinters.get(position - 1);                initPrinter(holder, printer);                break;            case NET_PRINTER:                PrinterInfo netPrinter = mPrinters.get(position - 2);                initPrinter(holder, netPrinter);                break;            case CLOUD_PRINTER:                if (position == getCount() - 1) {                    holder.divider.setVisibility(View.VISIBLE);                }                PrinterInfo cloudPrinter = mPrinters.get(position - 3);                initPrinter(holder, cloudPrinter);                break;        }        return convertView;    }

    private void initPrinter(PrinterManagerViewHolder holder, final PrinterInfo printerInfo) {        boolean connected = false;        holder.title.setText(printerInfo.name);

        HashMap<String, IPrinter> printers = PrinterManager.getInstance().getPrinterList();        if (printers.keySet().contains(printerInfo.mac)) {            connected = true;            holder.connect.setText("断开");            holder.connectIcon.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.ic_connect));        } else {            holder.connect.setText("连接");            holder.connectIcon.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.ic_break));        }

        holder.setting.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {                PrinterSettingActivity.navigateTo(mContext, printerInfo);            }        });        final boolean finalConnected = connected;        holder.connect.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {                if (listener != null) {                    listener.onConnectClicked(printerInfo, finalConnected);                }            }        });    }

    @Override    public int getItemViewType(int position) {        if (position == 0) {            return BLUETOOTH_HEADER;        } else if (position > 0 && position <= blueToothCount) {            return BLUETOOTH_PRINTER;        } else if (position == blueToothCount + 1) {            return NET_HEADER;        } else if (position > blueToothCount + 1 && position <= netCount + blueToothCount + 1) {            return NET_PRINTER;        } else if (position == netCount + blueToothCount + 2) {            return CLOUD_HEADER;        } else {            return CLOUD_PRINTER;        }    }

    @Override    public int getCount() {        if (mPrinters != null) {            return mPrinters.size() + 3;        }        return 0;    }

    @Override    public Object getItem(int position) {        return null;    }

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

    private class PrinterManagerViewHolder {

        private TextView headerTitle;        private ImageView headerIcon;        private ImageView headerAdd;        private View headerDivider;        // Printer        private TextView connect;        private TextView title;        private View divider;        private TextView setting;        private ImageView connectIcon;    }

    public interface OnItemFunctionClickListener {        void onConnectClicked(PrinterInfo printer, boolean connected);    }

}

我将 view 分为了6个 Type ,三种头部 Type 使用一种布局,三种打印机 Type 使用一种布局,然后总共用了一个 ViewHoloder 。
然后发现一个问题:
当我删除一个打印机之后,刷新界面的时候崩溃了
问题其实很简单:就是删除的打印机(BLUETOOTH_PRINTER Type)convertView 进入到缓存里面,然后下个 Item 的 Type 是 NET_HEADER Type,由于重用机制,这个 Item 会重用 convertView,此时这个 convertView 绑定的 ViewHoloder 是 Printer 部分,而自己要使用的是 Header 部分,其 view 都为 null了,导致空指针崩溃。
解决办法:添加代码

1234
@Overridepublic int getViewTypeCount() {    return 6;}

ListView 的缓存机制是可以针对不同 Type 来进行缓存的,当不复写这个方法的时候,其默认的实现是 返回1 ,所以导致getItemViewType返回的 Type 实际上是没有用的,不管是什么 Type, ListView 填充的 convertView 永远是一样的。所以,当改成 返回6 的时候, ListView 便会填充 6 种 convertView 了,所绑定的 ViewHoloder 具有的属性也会一样,就避免了空指针崩溃了。
当和同事讨论这点的时候,同事指出: 有几种布局,就用几种 Type,几种 ViewHoloder,一一对应才是官方推荐的行为。
自己想了下,确实是的。当网络打印机这个 Item 要显示的时候,如果缓存中有蓝牙打印机的 convertView,我是用不了的,因为他们的 Type 不一样。这样的一个做法,就是自己把 ListView 的缓存机制整乱了。
修改后的代码如下:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 大专栏  使用ListView多Type的错误姿势214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
public class  extends BaseAdapter {

    private final static int TYPE_HEADER = 0;    private final static int TYPE_PRINTER = 1;

    private Context mContext;    private LayoutInflater mInflater;    private OnItemFunctionClickListener listener;

    private ArrayList<PrinterInfo> mPrinters;    private int blueToothCount = 0;    private int netCount = 0;    private int cloudCount = 0;

    public (Context context, ArrayList<PrinterInfo> printers, SwipePartMenuListView listView) {        mContext = context;        mPrinters = printers;        mInflater = LayoutInflater.from(context);

        setNotSwipeItems(listView);    }

    private void setNotSwipeItems(SwipePartMenuListView listView) {        blueToothCount = 0;        netCount = 0;        cloudCount = 0;

        for (PrinterInfo info : mPrinters) {            if (info.printerType == PrinterInfo.TYPE_BLUETOOTH) {                blueToothCount++;            } else if (info.printerType == PrinterInfo.TYPE_NETWORK) {                netCount++;            } else if (info.printerType == PrinterInfo.TYPE_CLOUD) {                cloudCount++;            }        }

        List<Integer> titleList = new ArrayList<>();        titleList.add(0);        titleList.add(1 + blueToothCount);        titleList.add(2 + blueToothCount + netCount);        listView.setCannotSwipePositionList(titleList);    }

    public void setPrinters(ArrayList<PrinterInfo> printers, SwipePartMenuListView listView) {        this.mPrinters = printers;

        setNotSwipeItems(listView);    }

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

    @Override    public View getView(int position, View convertView, ViewGroup parent) {        HeaderViewHolder headerHolder = null;        PrinterViewHolder printerHolder = null;        int viewType = getItemViewType(position);        if (viewType == TYPE_HEADER) {            if (convertView == null) {                headerHolder = new HeaderViewHolder();                convertView = mInflater.inflate(R.layout.item_printer_title, parent, false);                headerHolder.headerTitle = (TextView) convertView.findViewById(R.id.printer_category_tv);                headerHolder.headerIcon = (ImageView) convertView.findViewById(R.id.printer_icon_iv);                headerHolder.headerAdd = (ImageView) convertView.findViewById(R.id.printer_add_device_iv);                headerHolder.headerDivider = convertView.findViewById(R.id.printer_title_divider);                convertView.setTag(headerHolder);            } else {                headerHolder = (HeaderViewHolder) convertView.getTag();            }        } else {            if (convertView == null) {                printerHolder = new PrinterViewHolder();                convertView = mInflater.inflate(R.layout.item_printer_devices, parent, false);                printerHolder.connect = (TextView) convertView.findViewById(R.id.printer_connect_tv);                printerHolder.divider = convertView.findViewById(R.id.printer_last_divider);                printerHolder.setting = (TextView) convertView.findViewById(R.id.printer_setting_tv);                printerHolder.title = (TextView) convertView.findViewById(R.id.printer_title_tv);                printerHolder.connectIcon = (ImageView) convertView.findViewById(R.id.printer_connect_iv);                convertView.setTag(printerHolder);            } else {                printerHolder = (PrinterViewHolder) convertView.getTag();            }        }        switch (viewType) {            case TYPE_HEADER:                if (headerHolder != null) {                    if (position == 0) {                        headerHolder.headerTitle.setText("蓝牙打印机");                        headerHolder.headerIcon.setImageResource(R.drawable.ic_printer_bluetooth);                        headerHolder.headerAdd.setImageResource(R.drawable.btn_setting_goods_add);                        headerHolder.headerAdd.setOnClickListener(new View.OnClickListener() {                            @Override                            public void onClick(View v) {                                BlueToothPrinterActivity.navigateTo(mContext, mPrinters);                            }                        });                    } else if (position == blueToothCount + 1) {                        headerHolder.headerTitle.setText("网络打印机");                        headerHolder.headerIcon.setImageResource(R.drawable.ic_printer_wifi);                        headerHolder.headerAdd.setImageResource(R.drawable.btn_setting_goods_add);                        headerHolder.headerAdd.setOnClickListener(new View.OnClickListener() {                            @Override                            public void onClick(View v) {//                                NetPrinterActivity.navigateTo(mContext);                            }                        });                    } else if (position == netCount + blueToothCount + 2) {                        headerHolder.headerTitle.setText("云打印机");                        headerHolder.headerIcon.setImageResource(R.drawable.ic_printer_cloud);                        headerHolder.headerAdd.setImageResource(R.drawable.btn_setting_goods_scan);                        headerHolder.headerAdd.setOnClickListener(new View.OnClickListener() {                            @Override                            public void onClick(View v) {//                                NetPrinterActivity.navigateTo(mContext);                            }                        });                        if (position == getCount() - 1) {                            headerHolder.headerDivider.setVisibility(View.VISIBLE);                        } else {                            headerHolder.headerDivider.setVisibility(View.GONE);                        }                    }                }                break;            case TYPE_PRINTER:                if (printerHolder != null) {                    int index;                    if (position > 0 && position <= blueToothCount) {                        index = position - 1;                    } else if (position > blueToothCount + 1 && position <= netCount + blueToothCount + 1) {                        index = position - 2;                    } else {                        index = position - 3;                        if (position == getCount() - 1) {                            printerHolder.divider.setVisibility(View.VISIBLE);                        } else {                            printerHolder.divider.setVisibility(View.GONE);                        }                    }                    PrinterInfo printer = mPrinters.get(index);                    initPrinter(printerHolder, printer);                }                break;            default:                break;        }        return convertView;    }

    private void initPrinter(PrinterViewHolder holder, final PrinterInfo printerInfo) {        if (holder != null) {            boolean connected = false;            holder.title.setText(printerInfo.name);

            HashMap<String, IPrinter> printers = PrinterManager.getInstance().getPrinterList();            if (printers.keySet().contains(printerInfo.mac)) {                connected = true;                holder.connect.setText("断开");                holder.connectIcon.setImageResource(R.drawable.ic_connect);            } else {                holder.connect.setText("连接");                holder.connectIcon.setImageResource(R.drawable.ic_break);            }

            holder.setting.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    PrinterSettingActivity.navigateTo(mContext, printerInfo);                }            });            final boolean finalConnected = connected;            holder.connect.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    if (listener != null) {                        listener.onConnectClicked(printerInfo, finalConnected);                    }                }            });        }    }

    public PrinterInfo getPrinterInfo(int position) {        int index;        if (position > 0 && position <= blueToothCount) {            index = position - 1;        } else if (position > blueToothCount + 1 && position <= netCount + blueToothCount + 1) {            index = position - 2;        } else {            index = position - 3;        }        return mPrinters.get(index);    }

    @Override    public int getItemViewType(int position) {        if (position == 0) {            return TYPE_HEADER;        } else if (position > 0 && position <= blueToothCount) {            return TYPE_PRINTER;        } else if (position == blueToothCount + 1) {            return TYPE_HEADER;        } else if (position > blueToothCount + 1 && position <= netCount + blueToothCount + 1) {            return TYPE_PRINTER;        } else if (position == netCount + blueToothCount + 2) {            return TYPE_HEADER;        } else {            return TYPE_PRINTER;        }    }

    @Override    public int getViewTypeCount() {        return 2;    }

    @Override    public int getCount() {        if (mPrinters != null) {            return mPrinters.size() + 3;        }        return 3;    }

    }

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

    private class HeaderViewHolder {        private TextView headerTitle;        private ImageView headerIcon;        private ImageView headerAdd;        private View headerDivider;    }

    private class PrinterViewHolder {        private TextView connect;        private TextView title;        private View divider;        private TextView setting;        private ImageView connectIcon;    }

    public interface OnItemFunctionClickListener {        void onConnectClicked(PrinterInfo printer, boolean connected);    }

}

这样的话,结构其实会更加清晰,拆分得更具体。
另外,注意一点: 代码中的 Type 类型 TYPE_HEADER 是从0开始的。这是因为不从 0 开始当 Adapter notifyDataSetChanged 时就会报错。举个栗子:

12
private final static int TYPE_HEADER = 5;private final static int TYPE_PRINTER = 6;

报错信息:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
FATAL EXCEPTION: mainProcess: com.maimairen.app.jinchuhuo.dev, PID: 15967java.lang.ArrayIndexOutOfBoundsException: length=2; index=5    at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6726)    at android.widget.ListView.layoutChildren(ListView.java:1644)    at android.widget.AbsListView.onLayout(AbsListView.java:2148)    at android.view.View.layout(View.java:16653)    at android.view.ViewGroup.layout(ViewGroup.java:5438)    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)    at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)    at android.view.View.layout(View.java:16653)    at android.view.ViewGroup.layout(ViewGroup.java:5438)    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)    at android.widget.FrameLayout.onLayout(FrameLayout.java:273)    at android.view.View.layout(View.java:16653)    at android.view.ViewGroup.layout(ViewGroup.java:5438)    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)    at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)    at android.view.View.layout(View.java:16653)    at android.view.ViewGroup.layout(ViewGroup.java:5438)    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)    at android.widget.FrameLayout.onLayout(FrameLayout.java:273)    at android.view.View.layout(View.java:16653)    at android.view.ViewGroup.layout(ViewGroup.java:5438)    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)    at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)    at android.view.View.layout(View.java:16653)    at android.view.ViewGroup.layout(ViewGroup.java:5438)    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)    at android.widget.FrameLayout.onLayout(FrameLayout.java:273)    at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2678)    at android.view.View.layout(View.java:16653)    at android.view.ViewGroup.layout(ViewGroup.java:5438)    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2198)    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1958)    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1134)    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6050)    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:860)    at android.view.Choreographer.doCallbacks(Choreographer.java:672)    at android.view.Choreographer.doFrame(Choreographer.java:608)    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:846)    at android.os.Handler.handleCallback(Handler.java:739)    at android.os.Handler.dispatchMessage(Handler.java:95)    at android.os.Looper.loop(Looper.java:148)    at android.app.ActivityThread.main(ActivityThread.java:5438)    at java.lang.reflect.Method.invoke(Native Method)    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)

可以看到,ListView 从缓存中去取 view 的时候,是用的 Type 的值来作为 index 的,所以 Type 类型一定是从0开始的
因为自己长期以来一直是之前的那种做法,错了太多次了,却没有及时发现错误,经过这次同事的指正,总算是纠正过来了。写篇博客备忘,忘性太大了~

原文地址:https://www.cnblogs.com/wangziqiang123/p/11718109.html

时间: 2024-10-04 01:52:19

使用ListView多Type的错误姿势的相关文章

eclipse import的项目报autowired cannot be resolved to a type的错误

eclipse报autowired cannot be resolved to a type的错误,一般情况是依赖的JDK或者jar包有问题,检查build path可以排查文件,我今天遇到这个情况,是因为我新导入的项目,没有在eclipse里maven关联,在eclipse里右键点击项目,然后选择第一项关联maven就好了.或者也许可以直接在import的时候选择maven目录下的引入maven项目选项. eclipse import的项目报autowired cannot be resolv

MYSQL中&#39;TYPE=MyISAM&#39;错误的解决方案

create 语句后面的TYPE=MyISAM TYPE=MyISAM 和 ENGINE=MyISAM 都是设置数据库存储引擎的语句 ,(老版本的MySQL使用TYPE而不是ENGINE(例如,TYPE = MYISAM). MySQL 5.1为向下兼容而支持这个语法,但TYPE现在被轻视,而ENGINE是首先的用法. 一般地,ENGINE 选项是不必要的:除非默认已经被改变了,MyISAM是默认存储引擎. 所以直接将原来TYPE=MyISAM 改成ENGINE=MyISAM 就可以了 MYSQ

Expected a type 的错误

在定义一个协议的时候,出现Expected a type 的错误? 解决办法:#import <UIKit/UIKit.h>

Undefined function or method &#39; &#39; for input arguments of type &#39;double&#39; ---错误解决办法

你如果要使用这个guo.m作为函数进行调用的话,那需要满足以下条件: 1.在guo.m里面要写成function的格式 function [output parmaters]=guo[input parameters] 2.拥有这个function的m文件的文件名要与这个函数名称一致,意思就是文件名要为 guo.m 3.调用这个function的m文件要与guo.m处于同一工作目录下 4.输入输出参数类型要与函数内部要求的类型一致 Undefined function or method ' '

MYSQL中&#39;TYPE=MyISAM&#39;错误的解决

错误提示:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' type=MyISAM default CHARACTER set utf8 collate utf8_general_ci' at line 1 解决: TYPE=MyISAM 和 ENGINE=MyISAM 都是设

SpringBoot 系列教程 JPA 错误姿势之环境配置问题

又回到 jpa 的教程上了,这一篇源于某个简单的项目需要读写 db,本想着直接使用 jpa 会比较简单,然而悲催的是实际开发过程中,发现了不少的坑:本文为错误姿势第一篇,Repository 接口无法注入问题 <!-- more --> I. 配置问题 新开一个 jpa 项目结合 springboot 可以很方便的实现,但是在某些环境下,可能会遇到自定义的 JpaRepository 接口无法注入问题 1. 基本配置 在 spring-boot 环境中,需要在pom.xml文件中,指定下面两个

Open quote is expected for attribute &quot;property&quot; associated with an element type &quot;result&quot;.错误

java  Mybatis 框架下的项目 报   Open quote is expected for attribute "property" associated with an element type "result".    这个错 眼快使瞎了,终于找到了 错误写法: <result column="DELETE_STATUS" property=delete_status  jdbcType="VARCHAR"

ListView 添加 HeaderView常见错误

1.addHeaderView异常: 最近在做通讯录开发时使用ListView,发现一个奇怪的问题:当添加一个ImageView 作为HeaderView时,发现ImageView长宽始终是1:1的大小,即调用 ListView.addHeaderView(mImageView) 之后mImageView尺寸布局被忽略.具体代码如下: list_view_header_layout.xml <?xml version="1.0" encoding="utf-8"

执行sql出现No Dialect mapping for JDBC type: -9错误

name的数据类型是nvarchar吗?如果是改为varchar类型应该能运行,但是这个治标不治本,这是hibernate没映射nvarchar 刚才整理了一下varchar和nvarchar的区别,然后用Hibernate映射到数据库时,发现String类型被映射为了varchar,就在网上找了一下怎样将String映射为nvarchar. 方法一: 对于String类型,你可能是这样映射的 [java] view plaincopy private String name; @Column(