kuaiyijia工作日志 - yunfanfan/Notes GitHub Wiki
kuaiyijia开发
搁置任务清单
- Dialog标题
开始二级页面UI的制作,首先梳理一遍有哪些功能点。
选择弹出框中的网点后,右上方的地址会改变,左上方是单位名。
一个单位有多个网点。也就是说这里是更换“当前单位的网点”。
参考:Android中实现底部弹出菜单栏_xys199719的博客-CSDN博客_android 底部弹出菜单
Toast toast=Toast.makeText(getApplicationContext(), "默认的Toast", Toast.LENGTH_SHORT);
getApplicationContext()
可获取当前context
遇到了报错,参考Dialog(四)——报错Unable to add window -- token null is not for an application_谷哥的小弟-CSDN博客
不可使用Builder builder=new Builder(getApplicationContext());
应该使用Builder builder=new Builder(MainActivity.this);
故将前面的getApplicationContext()
全部换成MainActivity.this
成功启动!
还需要给dialog加个标题
mChangNetPointDialog.setTitle("更换当前网点");
没有作用,未显示。搁置。
这里点击更换网点地点的按钮之后需要更改数据库中的值。
搜索运单号,在数据库中查询运单号。
点击Search按钮会在数据库中查询相应运单号。
扫的什么码?
I/Choreographer: Skipped 28 frames! The application may be doing too much work on its main thread.
只在测试手机魅族18上用摄像头扫码时会出现。
点击新运单后,会选择网点,然后进入“新增运单”页面填写表单:
第一行的目标网点可以点击进行更换。
进入发运管理
进入收货管理
填写退单表单
进入取货管理
开始实现无限轮播,以及添加图片
adapter读取图片资源,把之前的android.R.color.holo_orange_light
改成图片地址R.drawable.banner_index_1
就好了。
public VpAdapter(Context context) {
mContext = context;
if (backgrounds == null) {
backgrounds = new ArrayList<>();
backgrounds.add(R.drawable.banner_index_1);
backgrounds.add(R.drawable.banner_index_2);
backgrounds.add(R.drawable.banner_index_3);
backgrounds.add(android.R.color.holo_orange_light);
backgrounds.add(android.R.color.holo_purple);
}
}
学习笔记:使用ViewPager2实现简易轮播图 - 极客分享
按照ViewPager2打造Banner轮播图 - 掘金来实现
终于找到一个讲学不动也要学! ViewPager2新特性 - SegmentFault 思否
附上一段kotlin和java代码对比
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
currentPosition = position;
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
bannerVp.registerOnPageChangeCallback(object :
ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentPosition = position
}
override fun onPageScrollStateChanged(state: Int) {
//只有在空闲状态,才让自动滚动
if (state == ViewPager2.SCROLL_STATE_IDLE) {
if (currentPosition == 0) {
bannerVp.setCurrentItem(adapter.itemCount - 2, false)
} else if (currentPosition == adapter.itemCount - 1) {
bannerVp.setCurrentItem(1, false)
}
}
}
})
分析下面这段代码:
if (state == ViewPager2.SCROLL_STATE_IDLE) {
Log.d("getItemCount()=", Integer.toString(adapter.getItemCount()));
viewPager2.setCurrentItem(adapter.getItemCount() -2, false);
} else if (currentPosition == adapter.getItemCount() - 1) {
Log.d("getItemCount2()=", Integer.toString(adapter.getItemCount()));
viewPager2.setCurrentItem(1, false);
}
D/currentpage: 0 //刚进app第一个界面,position为0
D/currentpage: 1 //手动向右滑动,position到了1
D/getItemCount()=: 5 //进入了第一个if,执行了setCurrentItem(5-2)
D/currentpage: 3 //页面一共有5个,从0开始,分别是0,1,2,3,4
D/currentpage: 3 //页面3,0和3页面是一样的,1和4是一样的
之前代码基本是没问题的,就是第一个if条件写错了
按照这个表格来的话是完全没有问题的:
位置 | 处理 |
---|---|
currentPosition == 0
|
setCurrentItem(adapter.itemCount - 2 , false) |
currentPosition == adapter.itemCount - 1
|
setCurrentItem(1 , false) |
if (currentPosition == 0) {
viewPager2.setCurrentItem(adapter.getItemCount() -2, false);
} else if (currentPosition == adapter.getItemCount() - 1) {
viewPager2.setCurrentItem(1, false);
}
//自动连播
Thread mLoop = new Thread(new Runnable() {
@Override
public void run() {
int currentItem = viewPager2.getCurrentItem();
viewPager2.setCurrentItem(currentItem + 1);
viewPager2.postDelayed(this, 2500);
}
});
viewPager2.postDelayed(mLoop, 2500);
照这样写会有个小bug,没有找到原因,运行状态如下:
D/currentpage: 0
D/banner:: onPageScrollStateChanged: 到第0页了,设置page为3
D/currentpage: 3
D/currentpage: 1
D/currentpage: 3
D/currentpage: 3
D/currentpage: 3
D/currentpage: 3
D/currentpage: 3
D/currentpage: 3
D/currentpage: 3
D/currentpage: 3
D/currentpage: 4
到第四页了,没有促发连播,需要手动往右划一下,才能继续运行。
既然不会自动促发,那我就来手动促发,添加一段if判断
if (currentItem == 4) {
Log.d(TAG, "thread: 到第4页了,设置page为1");
viewPager2.setCurrentItem(1, false);
}
运行完美!
Android在Button按钮上同时显示文字和图片_程序员-CSDN博客
android:background="@null"
Android---给Linearlayout设置边框+弧度角_Yo.o-CSDN博客_linearlayout 边框
Android ImageButton 图片按钮 - Android 基础教程 - 简单教程,简单编程
用android系统的透明效果
android:background="@android:color/transparent"
昨天轮播图实现失败,今天重新学习了viewpage2,参考ViewPager 2 使用讲解 - 简书
梳理一下思路,首先有一个Activity,以及它对应的layout,这个layout中放置了一个viewpager2的view,代码如下:
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_h"
android:layout_width="match_parent"
android:layout_height="match_parent" />
然后在Activity中要初始化一个Adapter,并且把这个Adapter设置给这个viewPager2,代码如下:
ViewPager2 viewPager2 = findViewById(R.id.vp_h);
HorizontalVpAdapter adapter = new HorizontalVpAdapter(this);
viewPager2.setAdapter(adapter);
下面就要完成相对应的Adapter,代码如下:
public class HorizontalVpAdapter extends RecyclerView.Adapter<HorizontalVpAdapter.HorizontalVpViewHolder> {
private List<Integer> backgrounds;
private Context mContext;
public HorizontalVpAdapter(Context context) {
mContext = context;
if (backgrounds == null) {
backgrounds = new ArrayList<>();
backgrounds.add(android.R.color.holo_blue_bright);
backgrounds.add(android.R.color.holo_red_dark);
backgrounds.add(android.R.color.holo_green_dark);
backgrounds.add(android.R.color.holo_orange_light);
backgrounds.add(android.R.color.holo_purple);
}
}
@NonNull
@Override
public HorizontalVpViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new HorizontalVpViewHolder(LayoutInflater.from(mContext).inflate((R.layout.item_h_v), parent, false));
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull HorizontalVpViewHolder holder, int position) {
holder.mTextView.setText("第 " + (position + 1) + " 界面");
holder.mLinearLayout.setBackgroundResource(backgrounds.get(position));
}
@Override
public int getItemCount() {
if (backgrounds == null) {
return 0;
}
return backgrounds.size();
}
class HorizontalVpViewHolder extends RecyclerView.ViewHolder {
LinearLayout mLinearLayout;
TextView mTextView;
HorizontalVpViewHolder(@NonNull View itemView) {
super(itemView);
mLinearLayout = itemView.findViewById(R.id.ll_h_v);
mTextView = itemView.findViewById(R.id.tv_hv);
}
}
}
这其中涉及到了一个新的layout,我猜是用在viewpager2中显示具体不同内容的。
新的layout代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_h_v"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_hv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="16sp" />
</LinearLayout>
基本结构就完成了。
实现第一行的按钮
实现下面的轮播图,参考:Android 轮播图实现(新手易懂)_请叫我海贼王p的博客-CSDN博客_android轮播图实现
11.26开始着手App的界面重构。
以下是上半年的工作笔记
- 快捷收货
- 扫描订单
- 运价
- 装车码模块
- 查询车辆
- 生成装车码
-
- 扫码装车
-
- 扫码卸货
- 任务车辆
- 扫码发车
- 状态反馈
25号把数据操作代码写好了,除了数据查询部分。
26号开始写数据查询部分,数据处理都在database类里面,但是查询需要把查询结果返回回来。我就把返回值改成了ResultSet,这是一个结果集,封装了使用JDBC进行查询的结果,所以我需要的数据就在这个类里面。
现在数据是可以取出来了,测试也都没有问题,但是一放到我的代码里面就报错:
“'java.sql.Statement java.sql.Connection.createStatement()' on a null object reference”
解决办法:Android4.0以后不支持在主线程进行耗时操作,因此,如果设备是4.0版本以上的,要新开一条线程操作数据库。
最后开了一个线程就解决了!
现在能拿到数据了,可以开始着手生成装车码了。
车牌等数据是从子线程中得到的,但是setText不能在子线程中执行,如果把setText拿出来,又会导致数据消失。
解决办法:好像要用到线程间通信。
“Handler的创建方式有两种:一个是在主线程中创建,一个是在普通工作线程中创建,两种创建方法是不一样的。Handler在哪个线程中创建,那该线程就负责接收和处理消息,其它的线程只能发送消息。”
谁要收消息,谁就创建。
handleMessage的代码为什么最后执行(相较于点击事件的代码)?
sorry, the android camera encountered a problem. You may need to restart the device.
解决:“For Android 6+, because of the "permission" issue, If you got the message "Sorry, the camera encountered a problem. You may need to restart the device.", go to Settings - Apps - find "your app name" - select Permissions and switch on "Camera”.”
- 解决了线程间数据传递的问题
- 可根据字符串生成二维码
- 可打开相机扫描二维码。
- (1条消息) android 连接SQL Server数据库并进行数据操作_amberoot's Space-CSDN博客
- (1条消息) android直接链接sqlserver数据库_马腾蛟的博客-CSDN博客_android访问sqlserver数据库
- Java JDBC入门之四:通过ResultSet执行查询操作并处理结果集_码农回顾-CSDN博客
- JDBC那些事(二)——查询结果集_ResultSet_JUSTIN的博客-CSDN博客_jdbc遍历结果集
- Android线程间通信机制 - 简书
- android Handler Message传递参数_meixi_android的博客-CSDN博客
- Androidstudio中添加jar包的方法_zhenghongwu的博客-CSDN博客
业务逻辑不是很明白,文档中无任何描述。根据这个流程图,为什么扫描后如果不是装车码,就要去扫描订单码?

和扫码卸货的区别?是不是卸货是针对货运网点之间的,而收货是针对最后一站修理厂的?
运价页面的功能描述:“(1) 用户扫描一个订单码后,进入选择运价页面,选择对应运价,确认。(一个订单可能有多个商品条码,扫描每一个都需要进入运价页面,但如果没有扫描全部商品条码,会进入扫码不全页面,此功能需熟悉完后再进行开发)”
用户扫描的到底是订单码还是商品条码?并且选择运价之后需要修改数据库中什么表项?
强烈要求把需求文档中的“相关数据库及其字段”这一项补齐。
开始使用vivo x20真机进行调试

定位错误在线程内部sendMessage(msg)的地方。
根据解决Handler发送消息时:this message is already in use_xu_Melon的博客-CSDN博客所说,
报错的信息是指:发送的message正在消息队列中,不能被使用。
其实就是当我们想多次发送消息时,不能使用同一个消息的意思,所以解决的方法就是再次发送的时候重新获取一个新的消息.
检查自己的代码,发现我把sendMessage(msg)放在了循环内部,估计是这个原因,被运行了多次,所以消息就冲突了,所以我把这条语句拿出来放到循环外面,整个程序就正常了。

找到代码中显示“渝A66666”相关变量
由于之前直接导入的别人封装好的arr扫码模块,导致此处无法自己更改相关代码。现在回到上一步,重新添加扫码功能。
安装成功,可以获取扫码结果。
搬运人员先扫描装车码,与车辆绑定
疑问:搬运人员为什么要和车辆绑定?以什么形式绑定。
答:搬运人员相当于一条线,连接车辆和车辆需要运送的商品。
在bindDialog中点击确认后,还需添加扫码每个商品条形码的代码。
未在数据库中找到货物与车辆绑定的相关数据表。
绑定司机和车辆时,需要添加司机id,司机id如何获取?
Java 向数据库中输入 datetime类型数据
参考:Java 向数据库中输入 datetime类型数据_ChaoQun-CSDN博客_数据库datetime输入格式
之前每次插入数据都是把整个句子写死了,今天突然要插入变量,再去手动写value字符串就很麻烦。在网上发现了一段代码可以用?
填充。
Date date = new Date();
Timestamp timeStamp = new Timestamp(date.getTime());
sql= "insert into flowmeter2(total,std_flow,temp,press,time) values(?,?,?,?,?)";
try {
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, total);
ps.setString(2, std_flow);
ps.setString(3, temp);
ps.setString(4, press);
ps.setTimestamp(5, timeStamp);
ps.executeUpdate();
System.out.println("添加成功!");
connection.close();
但是必须要在加入数据的时候指定数据类型,故放弃此方法。
之后发现正是由于需要指定数据类型,所以还必须用此方法。
所以不能把数据库操作写在database类中,而是直接在需要的地方进行数据库连接操作。
Connection conn = database.getSQLConnection();
try {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,1);
ps.setString(2,ti_rq);
ps.setInt(3,mResultScan);
ps.setInt(4,1);
ps.setTimestamp(5,timeStamp);
ps.executeQuery();
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
最后要获取数据操作之后成功与否的状态,通过
ps.executeUpdate()//它会返回数据库中所操作的数据行数
如果它返回值为1就表明数据操作成功,绑定成功。
扫码发车功能基本开发完毕,可以绑定司机与车辆,并且显示绑定成功页面。
明天开始开发状态反馈功能。
数据库中需要修改运输记录表(XS_TRAN_INFO)
中的RESULTMSG
路途故障反馈说明。
开发完毕,能够正常更新数据库,并返回结果。
因为没有提供具体的订单表,所以此功能搁置
首先,扫码,然后查询结果是否是订单二维码。
如果是,就执行数据库操作,接单,并且进入选择运价页面,新建activity,跳转。
如果不是,就提示无此订单号
扫码商品条码,选择对应运价。
通过**货运运价表(PUB_FTRANPRICE)**中的什么表项来选择运价?
3.6.2.3中的页面设计有包装的规格,是通过货运包装类ID来选择吗?

关于订单表的说明,要登录他们的saas系统。上面有数据字段说明
明天后天直接用之前的旧mysql数据库表段来开发。
功能描述:收货人扫描订单上的二维码,进行绑定,同时更改订单状态
卸货是网点签收上个网点来的货物,扫码卸货后,货物的状态更改为”XXX网点 已到货”。
Mysql数据库:
[email protected] 端口3306 用户root 密码123456Abc
订单二维码根据表orders
中表项order_number
生成
商品条码储存在order_huowu_code
中,并且在表order_huowus
中的code_path
与订单二维码绑定,一个订单二维码对应多个商品条码。
订单状态:'0新建 1已接单(被抢单)2 已取货 3送货中 4到货 5完成 6异常 100取消'
修改订单状态:表orders
中表项order_status
设置为5
突然发现之前搜索车牌的时候未做判空处理,也就是说如果没有在数据库中找到相应车牌号,应该怎么做。
解答:根据rs.isBeforeFirst方法
当 ResultSet 为非空时,其游标指向第一条记录前面,若为空时由于不存在第一条记录,所以这时候游标也无法向指第一条记录前面
主线程不能做耗时操作,子线程中不能做更改UI操作,子线程需要通过handler才能来做更改UI的相关操作。
完成扫码卸货操作。
3.3
搬运人员相当于一条线,连接车辆和车辆需要运送的商品。
在bindDialog中点击确认后,还需添加扫码每个商品条形码的代码。
- 扫描装车码
- 判断是否绑定当前车辆
- 再去数据库查询是否是装车码
- 就去执行搬运人员和车辆的绑定操作
- 依次扫描每个商品条形码,绑定搬运人员和货物
- 先把商品条码insert在
order_huowu_code
中 - 然后update表
order_huowus
中的PORTER_ID
- 先把商品条码insert在
完成功能,未测试。
把之前的代码逻辑过一遍,改一下一些遗留的小问题。
搜索还缺少“模糊搜索”,等优优回来了看看。
之前写扫码功能的时候测试加了一个button,现在直接注释掉其点击事件。
点击确认,应该执行打印操作。此处还没开发。
注意点击扫码发车时,先去数据库查询是否有此装车码。
在xs_tran_info表中插入数据时,实际的司机id需要之后单独获取,并且需要解决第一个参数自增的方法。
目的地在线路到站表(PUB_LINES_D) 中 L_END 到站
使用范例如下
import com.example.kuaiyijia.ui.utility;
Message msgInfo = new Message();
mHandler.sendMessage(utility.getInfo(msgInfo,4,"PUB_VEHICLE","V_ID",mResultScan,"mV_no", "V_NO"));
明天应该完成一个变量名列表
- 注意点击扫码发车时,先去数据库查询是否有此装车码。
- 如果是装车码,就绑定司机和车辆,向xs_tran_info插入数据,线路id以及司机id从何处获取?
- 绑定成功后,更新界面车牌目的地数据
- 根据运输记录TI_ID来查询路途故障反馈说明RESULTMSG
(突然意识到,app还缺少根据对于登录人员获取个人基本信息的部分)
完成功能。
CREATE TABLE [dbo].[PUB_CARPORTER] (
[id] bigint IDENTITY(1,1),
[V_ID] bigint NOT NULL,
[PORTER_ID] int NULL,
CONSTRAINT [PK__PUB_CARP__3213E83F71D1E811] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[PUB_CARPORTER] SET (LOCK_ESCALATION = TABLE)
改了与huowu有关的几个表的描述,有关主键自增。
发现变量Request_code_scan
好像是用来控制不同的扫码过程的。
步骤五还要再认真思考一下。
变量Request_code_scan
确实是用来控制不同的扫码过程
扫码装车部分,暂时按照之前步骤来做。
5.2中“然后update表order_huowus
中的PORTER_ID
”,表中还需要一些测试数据。