電子拍賣系統開發第二天
一、搭建簡單的web伺服器
首先簡單看一下web工程目錄及其包的構建:
![](https://i.iter01.com/images/d919f84e9e5c4e181be64bd63de8df9e78dd917af311241d328e56447af92614.png)
匯入jar包
![](https://i.iter01.com/images/a903f028118fef9b65a54449c7e62b9785f393a2f7308c7cd499aa7c19fd96d8.png)
業務層介面:BussinessService.java
package com.xbmu.service;
import java.util.List;
import com.xbmu.bean.Bid;
import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.business.BidBean;
import com.xbmu.business.ItemBean;
import com.xbmu.business.KindBean;
import com.xbmu.exception.AuctionException;
/**
* 業務層介面(主要宣告一些主要的功能)
* @author Administrator
*
*/
public interface BussinessService{
/**
* 根據贏取者查詢物品
* @param winerId 贏取者的ID
* @return 贏取者獲得的全部物品
*/
List<ItemBean> getItemByWiner(Integer winerId)
throws AuctionException;
/**
* 查詢流拍的全部物品
* @return 全部流拍物品
*/
List<ItemBean> getFailItems()throws AuctionException;
/**
* 根據使用者名稱,密碼驗證登入是否成功
* @param username 登入的使用者名稱
* @param pass 登入的密碼
* @return 登入成功返回使用者ID,否則返回-1
*/
int validLogin(String username , String pass)
throws AuctionException;
/**
* 查詢使用者的全部出價
* @param userId 競價使用者的ID
* @return 使用者的全部出價
*/
List<BidBean> getBidByUser(Integer userId)
throws AuctionException;
/**
* 根據使用者查詢目前仍在拍賣中的全部物品
* @param userId 所屬者的ID
* @return 屬於當前使用者的、處於拍賣中的全部物品。
*/
List<ItemBean> getItemsByOwner(Integer userId)
throws AuctionException;
/**
* 查詢全部種類
* @return 系統中全部全部種類
*/
List<KindBean> getAllKind() throws AuctionException;
/**
* 新增物品
* @param item 新增的物品
* @param avail 有效天數
* @param kindId 物品種類ID
* @param userId 新增者的ID
* @return 新增物品的主鍵
*/
int addItem(Item item, int avail , int kindId , Integer userId)
throws AuctionException;
/**
* 新增種類
* @param kind 新增的種類
* @return 新增種類的主鍵
*/
int addKind(Kind kind) throws AuctionException;
/**
* 根據產品分類,獲取處於拍賣中的全部物品
* @param kindId 種類id;
* @return 該類的全部產品
*/
List<ItemBean> getItemsByKind(int kindId) throws AuctionException;
/**
* 根據種類id獲取種類名
* @param kindId 種類id;
* @return 該種類的名稱
*/
String getKind(int kindId) throws AuctionException;
/**
* 根據物品id,獲取物品
* @param itemId 物品id;
* @return 指定id對應的物品
*/
ItemBean getItem(int itemId) throws AuctionException;
/**
* 增加新的競價,並對競價使用者發郵件通知
* @param itemId 物品id;
* @param bid 競價
* @param userId 競價使用者的ID
* @return 返回新增競價記錄的ID
*/
int addBid(int itemId , Bid bid ,Integer userId)
throws AuctionException;
/**
* 根據時間來修改物品的贏取者
*/
void updateWiner()throws AuctionException;
}
完成登入功能模組:BussinessServiceImpl.java
package com.xbmu.service.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.xbmu.bean.Bid;
import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.bean.User;
import com.xbmu.business.BidBean;
import com.xbmu.business.ItemBean;
import com.xbmu.business.KindBean;
import com.xbmu.dao.AuctionUserDao;
import com.xbmu.dao.ItemDao;
import com.xbmu.dao.impl.AuctionUserDaoImpl;
import com.xbmu.dao.impl.ItemDaoImpl;
import com.xbmu.exception.AuctionException;
import com.xbmu.service.BussinessService;
public class BussinessServiceImpl implements BussinessService {
//---------------------使用者----------------------------
private AuctionUserDao userDao = new AuctionUserDaoImpl();
/**
* 根據使用者名稱,密碼驗證登入是否成功
* @param username 登入的使用者名稱
* @param pass 登入的密碼
* @return 登入成功返回使用者ID,否則返回-1
*/
public int validLogin(String username, String pass) throws AuctionException {
User user = userDao.findUserByNameAndPass(username, pass);
if(user!=null){
return user.getUser_id();
}
return -1;
}
//...
}
AuctionUserDao.javapackage com.xbmu.dao;
import com.xbmu.bean.User;
/**
* 資料訪問層,使用者介面
* @author Administrator
*
*/
public interface AuctionUserDao {
/**
* 驗證使用者登入
* @param username 使用者名稱
* @param pass 使用者密碼
* @return 驗證成功,返回一個使用者;否則返回null
*/
User findUserByNameAndPass(String username, String pass);
}
AuctionUserDaoImpl.javapackage com.xbmu.dao.impl;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.xbmu.bean.User;
import com.xbmu.dao.AuctionUserDao;
import com.xbmu.util.DBCPUtil;
public class AuctionUserDaoImpl implements AuctionUserDao {
private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
public User findUserByNameAndPass(String username, String pass) {
String sql = "select * from auction_user where username=? and userpass=?";
try {
List<User> userList = qr.query(sql, new BeanListHandler<User>(User.class), username,pass);
if (userList.size() == 1)
{
return (User)userList.get(0);
}
return null;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
LoginServlet.javapackage com.xbmu.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.service.BussinessService;
import com.xbmu.service.impl.BussinessServiceImpl;
/**
* Servlet3.0以後出現了註解。因此Servlet配置方式就有了兩種:
* 1、在web.xml檔案中配置。
* 2、通過註解配置。
* 比如:@WebServlet(urlPatterns="/android/login.jsp")配置後,客戶端就可以通過訪問此路徑訪問該servlet
*/
@WebServlet(urlPatterns = "/android/login.jsp")
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//獲取模式請求引數。android:表示客戶端請求地址,web:表示後臺請求地址
String mode = request.getParameter("mode");
if("android".equals(mode)){
Integer userId = validateLogin(request);
try {
JSONObject jsonObject = new JSONObject();
//把驗證的userId封裝成JSONObject
jsonObject.put("userId", userId);
//輸出響應
response.getWriter().println(jsonObject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}else if("web".equals(mode)){
Integer userId = validateLogin(request);
//轉發到首頁
request.getRequestDispatcher("/manage/index.jsp").forward(request, response);
}
}
/**
* 驗證使用者登入
* @param request
* @return 登入成功,返回使用者id
*/
private Integer validateLogin(HttpServletRequest request) {
String username = request.getParameter("username");
String password = request.getParameter("password");
//獲取業務邏輯物件
BussinessService service = new BussinessServiceImpl();
//驗證使用者登入
Integer userId = service.validLogin(username, password);
if (userId > 0) {
//將使用者ID放入HTTP session中,方便以後程式跟蹤使用者的登入狀態
request.getSession(true).setAttribute("userId", userId);
}
return userId;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登入頁面</title>
</head>
<body>
<div align="center">
<h2>歡迎您,使用電子拍賣系統</h2>
<form action="${pageContext.request.contextPath}/servlet/LoginServlet?mode=web" method="post">
使用者賬號:<input type="text" name="username" /><br/>
使用者密碼:<input type="password" name="password" /><br/>
<input type="submit" value="登入" />
</form>
</div>
</body>
</html>
請求地址:
服務端:
登入介面:http://localhost:8080/AuctionServer/manage/login.jsp
登入表單action="http://localhost:8080/AuctionServer/servlet/LoginServlet?mode=web"
客戶端:
登入訪問地址:
http://localhost:8080/AuctionServer/android/login.jsp?mode=android
(http://localhost:8080/AuctionServer/servlet/LoginServlet?mode=android)
二、客戶端開發:
搭建開發環境,建立專案:
![](https://i.iter01.com/images/84847d6eb4dbbb5549bdd07fca82c3604db6b4ca6f8845ce98dda6e78c88e3ab.png)
一、登入模組:
登入流程圖:
![](https://i.iter01.com/images/dfac88d98b9e43f8a3d716473ab8601fef19ff203b21f2b196059c7a68e11517.png)
FutureTask類介紹:
FutureTask是一種可以取消的非同步的計算任務。它的計算是通過Callable實現的,它等價於可以攜帶結果的Runnable,並且有三個狀態:等待、執行和完成。
完成包括所有計算以任意的方式結束,包括正常結束、取消和異常。
Future有個get方法而獲取結果只有在計算完成時獲取,否則會一直阻塞直到任務轉入完成狀態,然後會返回結果或者丟擲異常。
FutureTask有下面幾個重要的方法:
1.get()
阻塞一直等待執行完成拿到結果
Future有個get方法而獲取結果只有在計算完成時獲取,否則會一直阻塞直到任務轉入完成狀態,然後會返回結果或者丟擲異常。
FutureTask有下面幾個重要的方法:
1.get()
阻塞一直等待執行完成拿到結果
2.get(int timeout, TimeUnit timeUnit)
阻塞一直等待執行完成拿到結果,如果在超時時間內,沒有拿到丟擲異常
3.isCancelled()
是否被取消
4.isDone()
是否已經完成
5.cancel(boolean mayInterruptIfRunning)
試圖取消正在執行的任務
阻塞一直等待執行完成拿到結果,如果在超時時間內,沒有拿到丟擲異常
3.isCancelled()
是否被取消
4.isDone()
是否已經完成
5.cancel(boolean mayInterruptIfRunning)
試圖取消正在執行的任務
訪問網路的工具類HttpUtil.java
package com.xbmu.auction.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
* 訪問網路的工具類,採用了Apache 下的HttpClient類
* @author Administrator
*
*/
public class HttpUtil
{
// 建立HttpClient物件
public static HttpClient httpClient = new DefaultHttpClient();
public static final String BASE_URL =
"http://10.0.2.2:8080/AuctionServer/android/";
/**
*
* @param url 傳送請求的URL
* @return 伺服器響應字串
* @throws Exception
*/
public static String getRequest(final String url)
throws Exception
{
FutureTask<String> task = new FutureTask<String>(
new Callable<String>()
{
@Override
public String call() throws Exception
{
// 建立HttpGet物件。
HttpGet get = new HttpGet(url);
// 傳送GET請求
HttpResponse httpResponse = httpClient.execute(get);
// 如果伺服器成功地返回響應
if (httpResponse.getStatusLine()
.getStatusCode() == 200)
{
// 獲取伺服器響應字串
String result = EntityUtils
.toString(httpResponse.getEntity());
return result;
}
return null;
}
});
new Thread(task).start();
return task.get();
}
/**
* @param url 傳送請求的URL
* @param params 請求引數
* @return 伺服器響應字串
* @throws Exception
*/
public static String postRequest(final String url
, final Map<String ,String> rawParams)throws Exception
{
FutureTask<String> task = new FutureTask<String>(
new Callable<String>()
{
@Override
public String call() throws Exception
{
// 建立HttpPost物件。
HttpPost post = new HttpPost(url);
// 如果傳遞引數個數比較多的話可以對傳遞的引數進行封裝
List<NameValuePair> params =
new ArrayList<NameValuePair>();
for(String key : rawParams.keySet())
{
//封裝請求引數
params.add(new BasicNameValuePair(key
, rawParams.get(key)));
}
// 設定請求引數
post.setEntity(new UrlEncodedFormEntity(
params, "utf-8"));
// 傳送POST請求
HttpResponse httpResponse = httpClient.execute(post);
// 如果伺服器成功地返回響應
if (httpResponse.getStatusLine()
.getStatusCode() == 200)
{
// 獲取伺服器響應字串
String result = EntityUtils
.toString(httpResponse.getEntity());
return result;
}
return null;
}
});
new Thread(task).start();
return task.get();
}
}
LoginActivity.javapackage com.xbmu.auction;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.xbmu.auction.util.DialogUtil;
import com.xbmu.auction.util.HttpUtil;
/**
* 登入介面的Activity
* @author Administrator
*
*/
public class LoginActivity extends Activity {
private EditText etUser;
private EditText etPwd;
private Button btnLogin;
private Button btnCancel;
private String username;
private String password;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
etUser = (EditText) findViewById(R.id.et_user);
etPwd = (EditText) findViewById(R.id.et_pwd);
btnLogin = (Button) findViewById(R.id.btn_Login);
btnCancel = (Button) findViewById(R.id.btn_Cancel);
btnLogin.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//1.校驗使用者資訊
if(validate()){
//2.如果資訊正確,登入應用
if(loginPro()){
//3.登入成功,啟動主Activity
Intent intent = new Intent(LoginActivity.this, AuctionClientActivity.class);
startActivity(intent);
//結束該Activity
finish();
}else{
DialogUtil.showDialog(LoginActivity.this, "使用者名稱或者密碼錯誤,請重新輸入!", false);
}
}
}
});
}
/**用於登入資訊驗證成功後,登入程式*/
protected boolean loginPro() {
try {
JSONObject jsonObject = query(username,password);
//如果userId > 0
if(jsonObject.getInt("userId") > 0){
return true;
}
} catch (Exception e) {
DialogUtil.showDialog(this, "伺服器響應異常,請稍後再試!", false);
e.printStackTrace();
}
return false;
}
/**
* 傳送請求的方法
* @param username
* @param password
* @return
* @throws Exception
*/
private JSONObject query(String username, String password) throws Exception {
//使用Map封裝請求引數
Map<String, String> map = new HashMap<String, String>();
map.put("username", username);
map.put("password", password);
//傳送請求的URL
String url = HttpUtil.BASE_URL+"login.jsp"+"?mode=android";
System.out.println(HttpUtil.postRequest(url, map));
//傳送請求
return new JSONObject(HttpUtil.postRequest(url, map));
}
/**對使用者輸入的使用者名稱、密碼進行校驗*/
protected boolean validate() {
username = etUser.getText().toString().trim();
password = etPwd.getText().toString().trim();
if(TextUtils.isEmpty(username)){
DialogUtil.showDialog(this, "使用者賬號是必填項", false);
return false;
}
if(TextUtils.isEmpty(password)){
DialogUtil.showDialog(this, "使用者密碼是必填項", false);
return false;
}
return true;
}
}
登入介面使用了表格佈局,我們這裡簡單介紹下表格佈局的常用屬性:
android:shrinkColumns:設定允許被收縮的列的列序號。多個序列號之間用逗號隔開。
android:stretchColumns:設定允許被拉伸的列的列序號。多個序列號之間用逗號隔開。
android:collapseColumns:設定需要被隱藏的列的列序號。多個序列號之間用逗號隔開。
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:stretchColumns="1">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/hello"
android:scaleType="fitCenter"
android:src="@drawable/logo" />
<TextView
android:id="@+id/TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="@dimen/title_padding"
android:text="@string/welcome"
android:textSize="@dimen/label_font_size" />
<!-- 輸入使用者名稱的行 -->
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/user_name"
android:textSize="@dimen/label_font_size" />
<EditText
android:id="@+id/et_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</TableRow>
<!-- 輸入密碼的行 -->
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/user_pass"
android:textSize="@dimen/label_font_size" />
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:text="" />
</TableRow>
<!-- 定義登入、取消按鈕的行 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_Login"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="@string/login" />
<Button
android:id="@+id/btn_Cancel"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="@string/cancel" />
</LinearLayout>
</TableLayout>
DialogUtil.javapackage com.xbmu.auction.util;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.view.View;
import com.xbmu.auction.AuctionClientActivity;
/**
* 專案要用到許多對話方塊,這裡封裝一個對話方塊的工具類。便於顯示對話方塊
* @author Administrator
*
*/
public class DialogUtil {
/**
* 定義一個顯示訊息的對話方塊
*
* @param context 上下文
* @param msg 對話方塊顯示的描述資訊
* @param goHome 標記,為true表示登入成功,為false登入失敗
*/
public static void showDialog(final Context context, String msg,
boolean goHome) {
//建立一個AlertDialog.Builder物件
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(msg);
builder.setCancelable(false);
if (goHome) {
//登入成功,跳轉到AuctionClientActivity(也就是應用程式的主介面)介面
builder.setPositiveButton("確定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(context,
AuctionClientActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
});
} else {
builder.setPositiveButton("確定", null);
}
builder.create().show();
}
/**
* 定義一個顯示指定元件(佈局)的對話方塊
* @param context
* @param view
*/
public static void showDialog(Context context, View view) {
new AlertDialog.Builder(context).setView(view).setCancelable(false)
.setPositiveButton("確定", null).create().show();
}
}
AuctionClientActivity.javapackage com.xbmu.auction;
import android.app.Activity;
import android.os.Bundle;
/**
* 應用程式主介面
* @author Administrator
*
*/
public class AuctionClientActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
res/values/strings.xml<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_settings">Settings</string>
<string name="app_name">電子拍賣</string>
<string name="welcome">歡迎使用電子拍賣系統</string>
<string name="hello_world">Hello world!</string>
<string name="user_name">使用者賬號:</string>
<string name="user_pass">使用者密碼</string>
<string name="login">登入</string>
<string name="cancel">取消</string>
<string name="hello">Hello World, Login!</string>
</resources>
res/values/dimens.xml<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="title_padding">10dp</dimen>
<dimen name="label_font_size">20dp</dimen>
</resources>
記得在清單檔案中加入訪問網路的許可權:<uses-permission android:name="android.permission.INTERNET"/>
執行效果:(記得先開啟伺服器)![](https://i.iter01.com/images/71bdca9cb206d415c25cdc8e791b4fc830acefb0451840a4074fd16cf536e311.gif)
二、進入主頁面
auction_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="@dimen/title_padding"
android:text="@string/welcome"
android:textSize="@dimen/label_font_size" />
<ListView
android:id="@+id/auction_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/auction_list" />
</LinearLayout>
AuctionListFragment.java
package com.xbmu.auction.view;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.xbmu.auction.Callbacks;
import com.xbmu.auction.R;
/**
* 自定義的Fragment,該Fragment種顯示一個ListView,每個ListView條目代表一個系統功能
*
* @author Administrator
*
*/
public class AuctionListFragment extends Fragment {
ListView auctionList;
private Callbacks mCallbacks;
/**重寫該方法,該方法返回的View將作為Fragment顯示的元件*/
@Override
public View onCreateView(LayoutInflater inflater
, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.auction_list,
container, false);
auctionList = (ListView) rootView.findViewById(
R.id.auction_list);
// 為ListView的列表項的單擊事件繫結事件監聽器
auctionList.setOnItemClickListener(new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
mCallbacks.onItemSelected(position , null);
}
});
return rootView;
}
/**當該Fragment被新增、顯示到Activity時,回撥該方法*/
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
// 如果Activity沒有實現Callbacks介面,丟擲異常
if (!(activity instanceof Callbacks))
{
throw new IllegalStateException(
"AuctionListFragment所在的Activity必須實現Callbacks介面!");
}
// 把該Activity當成Callbacks物件
mCallbacks = (Callbacks) activity;
}
/**當該Fragment從它所屬的Activity中被刪除時回撥該方法*/
@Override
public void onDetach()
{
super.onDetach();
// 將mCallbacks賦為null。
mCallbacks = null;
}
/**
* 設定:啟用條目點選
* @param activateOnItemClick
*/
public void setActivateOnItemClick(boolean activateOnItemClick)
{ //設定ListView的選擇行為。該屬性支援如下屬性值
/*
* none:不顯示任何選中項
* singleChoice:允許單選
*/
auctionList.setChoiceMode(activateOnItemClick
? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
}
Callbacks.java
package com.xbmu.auction;
import android.os.Bundle;
/**
* 定義一個回撥介面,裡面定義一些回撥方法。用於優化程式碼
* @author Administrator
*
*/
public interface Callbacks {
/**
* 單個條目被選中,呼叫該方法。
* @param id
* @param bundle
*/
public void onItemSelected(Integer id,Bundle bundle);
}
將Fragment新增到Activity中有如下兩種方法:
1、在佈局檔案中使用<fragment />元素新增到Fragment,<fragment />元素的android:name屬性指定Fragment的實現類。
2、在java程式碼中通過FragmentTransaction物件的add()方法來新增Fragment
activity_main.xml<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<!--新增一個自定義的Fragment -->
<fragment
android:name="com.xbmu.auction.view.AuctionListFragment"
android:id="@+id/auction_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Activity獲取它包含的Fragment:呼叫Activity關聯的FragmentManager的findFragmentById(int id)或findFragmentByTag(String tag)方法即可獲取指定的Fragment
AuctionClientActivity.javapackage com.xbmu.auction;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import com.xbmu.auction.activity.ChooseKind;
import com.xbmu.auction.activity.ManageItem;
import com.xbmu.auction.activity.ManageKind;
import com.xbmu.auction.activity.ViewBid;
import com.xbmu.auction.activity.ViewItem;
import com.xbmu.auction.view.AuctionListFragment;
/**
* 應用程式主介面
* @author Administrator
*
*/
public class AuctionClientActivity extends Activity implements Callbacks{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getFragmentManager();
AuctionListFragment auctionList = (AuctionListFragment) fm.findFragmentById(R.id.auction_list);
auctionList.setActivateOnItemClick(true);
}
@Override
public void onItemSelected(Integer id, Bundle bundle) {
Intent intent = null;
switch ((int)id) {
// 檢視競得物品
case 0:
// 啟動ViewItem Activity
intent = new Intent(this, ViewItem.class);
// action屬性為請求的Servlet地址。
intent.putExtra("action", "viewSucc.jsp");
startActivity(intent);
break;
// 瀏覽流拍物品
case 1:
// 啟動ViewItem Activity
intent = new Intent(this, ViewItem.class);
// action屬性為請求的Servlet的URL。
intent.putExtra("action", "viewFail.jsp");
startActivity(intent);
break;
// 管理物品種類
case 2:
// 啟動ManageKind Activity
intent = new Intent(this, ManageKind.class);
startActivity(intent);
break;
// 管理物品
case 3:
// 啟動ManageItem Activity
intent = new Intent(this, ManageItem.class);
startActivity(intent);
break;
// 瀏覽拍賣物品(選擇物品種類)
case 4:
// 啟動ChooseKind Activity
intent = new Intent(this, ChooseKind.class);
startActivity(intent);
break;
// 檢視自己的競標
case 5:
// 啟動ViewBid Activity
intent = new Intent(this, ViewBid.class);
startActivity(intent);
break;
}
}
}
提示:在介面佈局檔案中使用<fragment />元素新增Fragment時,可以為<fragment />元素指定android:id或android:tag屬性,這兩個屬性都可用於標識該Fragment,接下來Activity將可通過findFragmentById(int id)或findFragmentByTag(String tag)來獲取該Fragment。
FragmentActivity.java
FragmentActivity.java
package com.xbmu.auction;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.widget.LinearLayout;
public abstract class FragmentActivity extends Activity{
private static final int ROOT_CONTAINER_ID = 0x90001;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
setContentView(layout);
layout.setId(ROOT_CONTAINER_ID);
getFragmentManager().beginTransaction()
.replace(ROOT_CONTAINER_ID , getFragment())
.commit();
}
protected abstract Fragment getFragment();
}
ViewItem.javapackage com.xbmu.auction.activity;
import android.app.Fragment;
import com.xbmu.auction.FragmentActivity;
/**
* 瀏覽流拍物品
* @author Administrator
*/
public class ViewItem extends FragmentActivity {
@Override
protected Fragment getFragment() {
// TODO Auto-generated method stub
return null;
}
}
其中ChooseKind.java、ManageItem.java、ManageKind.java、ViewBid.java這幾個檔案暫時性和ViewItem的內容差不多。
res/values/array.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="auction_list">
<item>檢視競得物品</item>
<item>瀏覽流拍物品</item>
<item>管理物品種類</item>
<item>管理物品</item>
<item>瀏覽拍賣物品</item>
<item>檢視自己的競標</item>
</string-array>
</resources>
res/values/strings.xml<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_settings">Settings</string>
<string name="app_name">電子拍賣</string>
<string name="welcome">歡迎使用電子拍賣系統</string>
<string name="hello_world">Hello world!</string>
<string name="user_name">使用者賬號:</string>
<string name="user_pass">使用者密碼</string>
<string name="login">登入</string>
<string name="cancel">取消</string>
<string name="hello">Hello World, Login!</string>
<string name="manage_kind">系統的所有物品種類</string>
<string name="manage_item">你當前的拍賣物品</string>
<string name="view_bid">你參與競標的物品</string>
<string name="choose_kind">請選擇一個物品的種類</string>
</resources>
在清單檔案中註冊:
<activity
android:name=".AuctionClientActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.xbmu.auction.activity.ViewItem"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.xbmu.auction.activity.ManageKind"
android:label="@string/manage_kind" >
</activity>
<activity
android:name="com.xbmu.auction.activity.ManageItem"
android:label="@string/manage_item" >
</activity>
<activity
android:name="com.xbmu.auction.activity.ViewBid"
android:label="@string/view_bid" >
</activity>
<activity
android:name="com.xbmu.auction.activity.ChooseKind"
android:label="@string/choose_kind" >
</activity>
執行效果:![](https://i.iter01.com/images/04ef3537536a84d3747903f5c09ce3df46a95d3bb34aef3b748530b4f2a5dfcd.gif)
三、實現主頁面各個功能:
3.1:瀏覽流拍物品:
在伺服器上寫瀏覽流拍物品功能:
BussinessServiceImpl.java
package com.xbmu.service.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.xbmu.bean.Bid;
import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.bean.User;
import com.xbmu.business.BidBean;
import com.xbmu.business.ItemBean;
import com.xbmu.business.KindBean;
import com.xbmu.dao.AuctionUserDao;
import com.xbmu.dao.ItemDao;
import com.xbmu.dao.KindDao;
import com.xbmu.dao.impl.AuctionUserDaoImpl;
import com.xbmu.dao.impl.ItemDaoImpl;
import com.xbmu.dao.impl.KindDaoImpl;
import com.xbmu.exception.AuctionException;
import com.xbmu.service.BussinessService;
public class BussinessServiceImpl implements BussinessService {
//...
// ---------------------物品----------------------------
private ItemDao itemDao = new ItemDaoImpl();
/**
* 查詢流拍的全部物品
*
* @return 全部流拍物品
*/
public List<ItemBean> getFailItems() throws AuctionException {
try {
List<Item> items = itemDao.findItemByState(3);
List<ItemBean> result = new ArrayList<ItemBean>();
for (Iterator<Item> it = items.iterator(); it.hasNext();) {
ItemBean ib = new ItemBean();
initItem(ib, it.next());
result.add(ib);
}
return result;
} catch (Exception e) {
throw new AuctionException("查詢流拍物品出現異常,請重試");
}
}
//....
/**
* 將一個Item PO轉換成ItemBean的VO
* @param ib ItemBean的VO
* @param item Item的PO
*/
private void initItem(ItemBean ib, Item item) {
ib.setId(item.getItem_id());
ib.setName(item.getItem_name());
ib.setDesc(item.getItem_desc());
ib.setRemark(item.getItem_remark());
if (item.getKind() != null)
ib.setKind(item.getKind().getKind_name());
if (item.getOwner() != null)
ib.setOwner(item.getOwner().getUsername());
if (item.getWiner() != null)
ib.setWiner(item.getWiner().getUsername());
ib.setAddTime(item.getAddtime());
ib.setEndTime(item.getEndtime());
if (item.getItemState() != null)
ib.setState(item.getItemState().getState_name());
ib.setInitPrice(item.getInit_price());
ib.setMaxPrice(item.getMax_price());
}
}
ItemDao.java
package com.xbmu.dao;
import java.util.List;
import com.xbmu.bean.Item;
/**
* 物品介面
* @author Administrator
*
*/
public interface ItemDao{
/**
* 根據物品狀態查詢物品
* @param stateId 狀態Id;
* @return 該狀態下的全部物品
*/
List<Item> findItemByState(Integer stateId);
}
ItemDaoImpl.javapackage com.xbmu.dao.impl;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.xbmu.bean.Item;
import com.xbmu.bean.Kind;
import com.xbmu.bean.User;
import com.xbmu.dao.ItemDao;
import com.xbmu.util.DBCPUtil;
public class ItemDaoImpl implements ItemDao {
QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
/**
* 根據物品狀態查詢物品
* @param stateId 狀態id;
* @return 該狀態下的全部物品
*/
public List<Item> findItemByState(Integer stateId) {
try {
String sql = "select * from item where state_id = ?";
List<Item> itemList = qr.query(sql, new BeanListHandler<Item>(Item.class),stateId);
//遍歷物品,設定種類,贏取者,擁有者的屬性。
for (Item item : itemList) {
//設定種類
String kindSql = "select * from kind where kind_id = (select kind_id from item where state_id=?)";
Kind kind = qr.query(kindSql, new BeanHandler<Kind>(Kind.class), stateId);
item.setKind(kind);
//設定擁有者使用者
String ownerSql = "select * from auction_user where user_id = (select owner_id from item where state_id=?)";
User owner = qr.query(ownerSql, new BeanHandler<User>(User.class), stateId);
item.setOwner(owner);
//設定贏取者使用者
String winerSql = "select * from auction_user where user_id = (select winer_id from item where state_id=?)";
User winer = qr.query(winerSql, new BeanHandler<User>(User.class), stateId);
item.setWiner(winer);
System.out.println(item.toString());
}
return itemList;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//...
}
ViewFailServlet.java
package com.xbmu.web.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import com.xbmu.business.ItemBean;
import com.xbmu.service.BussinessService;
import com.xbmu.service.impl.BussinessServiceImpl;
/**
* 檢視流拍物品的Servlet
*
* @author Administrator
*
*/
@WebServlet(urlPatterns = "/android/viewFail.jsp")
public class ViewFailServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//獲取請求引數,這個引數標記的是返回的json資料,用於提供給客戶端
String mode = request.getParameter("mode");
// 獲取業務邏輯物件
BussinessService service = new BussinessServiceImpl();
// 查詢所有流拍的物品
List<ItemBean> items = service.getFailItems();
if("android".equals(mode)){
//返回json資料提供給客戶端
JSONArray jsonArray = new JSONArray(items);
response.getWriter().println(jsonArray.toString());
}else if("web".equals(mode)){
//將資料儲存在request域中,顯示在服務端介面上
request.setAttribute("items", items);
request.getRequestDispatcher("/manage/viewFail.jsp").forward(
request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
執行效果:
![](https://i.iter01.com/images/1ef85cce571629b372c226d1e144ac33f938ad5c148e9b7605d488bd4d82f69d.png)
返回json物件:
![](https://i.iter01.com/images/361cb5639b8b5a01083fc140455ca5d6ef940732e767164fbb51bd6764929108.png)
在客戶端上寫瀏覽流拍物品功能:
view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/sub_title_margin"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="@+id/view_titile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/view_succ"
android:textSize="@dimen/label_font_size" />
<!-- 定義返回按鈕 -->
<Button
android:id="@+id/bn_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/label_font_size"
android:background="@drawable/home" />
</LinearLayout>
<!-- 檢視物品列表的ListView -->
<ListView
android:id="@+id/succList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
res/drawable/tv_bg.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:color="#888"
android:width="2dp"/>
<!-- 設定圓角矩形 -->
<corners android:radius="2dp" />
<solid android:color="#fff"/>
</shape>
res/values/styles.xml <style name="tv_show">
<item name="android:textColor">#000</item>
<item name="android:textSize">20sp</item>
<item name="android:padding">4dp</item>
<item name="android:background">@drawable/tv_bg</item>
</style>
package com.xbmu.auction.fragment;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.xbmu.auction.R;
import com.xbmu.auction.adapter.JSONArrayAdapter;
import com.xbmu.auction.listener.HomeListener;
import com.xbmu.auction.util.DialogUtil;
import com.xbmu.auction.util.HttpUtil;
public class ViewItemFragment extends Fragment
{
Button bnHome;
ListView succList;
TextView viewTitle;
@Override
public View onCreateView(LayoutInflater inflater
, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.view_item
, container , false);
// 獲取介面上的返回按鈕
bnHome = (Button) rootView.findViewById(R.id.bn_home);
succList = (ListView) rootView.findViewById(R.id.succList);
viewTitle = (TextView) rootView.findViewById(R.id.view_titile);
// 為返回按鈕的單擊事件繫結事件監聽器
bnHome.setOnClickListener(new HomeListener(getActivity()));
//Bundle.getArguments():如果有的話,當fragment初始化的時候,返回提供的引數。
String action = getArguments().getString("action");
// 定義傳送請求的URL
String url = HttpUtil.BASE_URL + action+"?mode=android";
// 如果是檢視流拍物品,修改標題
if (action.equals("viewFail.jsp"))
{
viewTitle.setText(R.string.view_fail);
}
try
{
// 向指定URL傳送請求,並把伺服器響應轉換成JSONArray物件
JSONArray jsonArray = new JSONArray(HttpUtil
.getRequest(url));
// 將JSONArray包裝成Adapter
JSONArrayAdapter adapter = new JSONArrayAdapter(getActivity()
, jsonArray, "name", true);
succList.setAdapter(adapter);
}
catch (Exception e)
{
DialogUtil.showDialog(getActivity(), "伺服器響應異常,請稍後再試!", false);
e.printStackTrace();
}
succList.setOnItemClickListener(new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
// 檢視指定物品的詳細情況。
viewItemDetail(position);
}
});
return rootView;
}
private void viewItemDetail(int position)
{
// 載入detail.xml介面佈局代表的檢視
View detailView = getActivity().getLayoutInflater()
.inflate(R.layout.detail, null);
// 獲取detail.xml介面佈局中的文字框
TextView itemName = (TextView) detailView
.findViewById(R.id.itemName);
TextView itemKind = (TextView) detailView
.findViewById(R.id.itemKind);
TextView maxPrice = (TextView) detailView
.findViewById(R.id.maxPrice);
TextView itemRemark = (TextView) detailView
.findViewById(R.id.itemRemark);
// 獲取被單擊的列表項
JSONObject jsonObj = (JSONObject) succList.getAdapter().getItem(
position);
try
{
// 通過文字框顯示物品詳情
itemName.setText(jsonObj.getString("name"));
itemKind.setText(jsonObj.getString("kind"));
maxPrice.setText(jsonObj.getString("maxPrice"));
itemRemark.setText(jsonObj.getString("desc"));
}
catch (JSONException e)
{
e.printStackTrace();
}
DialogUtil.showDialog(getActivity(), detailView);
}
}
detail.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="1" >
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/item_name"
android:textSize="@dimen/label_font_size" />
<TextView
android:id="@+id/itemName"
style="@style/tv_show"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/item_kind"
android:textSize="@dimen/label_font_size" />
<TextView
android:id="@+id/itemKind"
style="@style/tv_show"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/win_price"
android:textSize="@dimen/label_font_size" />
<TextView
android:id="@+id/maxPrice"
style="@style/tv_show"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/remark"
android:textSize="@dimen/label_font_size" />
<TextView
android:id="@+id/itemRemark"
style="@style/tv_show"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
package com.xbmu.auction.listener;
import com.xbmu.auction.AuctionClientActivity;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
public class HomeListener implements OnClickListener
{
private Activity activity;
public HomeListener(Activity activity)
{
this.activity = activity;
}
@Override
public void onClick(View source)
{
Intent i = new Intent(activity , AuctionClientActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(i);
}
}
JSONArrayAdapter.javapackage com.xbmu.auction.adapter;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import com.xbmu.auction.R;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class JSONArrayAdapter extends BaseAdapter
{
private Context ctx;
// 定義需要包裝的JSONArray物件
private JSONArray jsonArray;
// 定義列表項顯示JSONObject物件的哪個屬性
private String property;
private boolean hasIcon;
public JSONArrayAdapter(Context ctx
, JSONArray jsonArray, String property
, boolean hasIcon)
{
this.ctx = ctx;
this.jsonArray = jsonArray;
this.property = property;
this.hasIcon = hasIcon;
}
@Override
public int getCount()
{
return jsonArray.length();
}
@Override
public Object getItem(int position)
{
return jsonArray.optJSONObject(position);
}
@Override
public long getItemId(int position)
{
try
{
// 返回物品的ID
return ((JSONObject)getItem(position)).getInt("id");
}
catch (JSONException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
// 定義一個線性佈局管理器
LinearLayout linear = new LinearLayout(ctx);
// 設定為水平的線性佈局管理器
linear.setOrientation(0);
// 建立一個ImageView
ImageView iv = new ImageView(ctx);
iv.setPadding(10, 0, 20, 0);
iv.setImageResource(R.drawable.item);
// 將圖片新增到LinearLayout中
linear.addView(iv);
// 建立一個TextView
TextView tv = new TextView(ctx);
try
{
// 獲取JSONArray陣列元素的property屬性
String itemName = ((JSONObject)getItem(position))
.getString(property);
// 設定TextView所顯示的內容
tv.setText(itemName);
}
catch (JSONException e)
{
e.printStackTrace();
}
tv.setTextSize(20);
if (hasIcon)
{
// 將TextView新增到LinearLayout中
linear.addView(tv);
return linear;
}
else
{
return tv;
}
}
}
ViewItem.javapackage com.xbmu.auction.activity;
import android.app.Fragment;
import android.os.Bundle;
import com.xbmu.auction.FragmentActivity;
import com.xbmu.auction.fragment.ViewItemFragment;
/**
* 瀏覽流拍物品
*
* @author Administrator
*/
public class ViewItem extends FragmentActivity {
// 重寫getFragment()方法,該Activity顯示該方法返回的Fragment
@Override
protected Fragment getFragment() {
/**
* 思路:Activity向Fragment傳遞資料:在Activity中建立Bundle資料包,
* 並呼叫Fragment的setArguments(Bundle bundle) 方法即可將Bundle資料包傳給Fragment。
*/
ViewItemFragment fragment = new ViewItemFragment();
// 攜帶資料的資料包物件
Bundle arguments = new Bundle();
// 向資料包物件中裝資料
arguments.putString("action", getIntent().getStringExtra("action"));
//將Bundle資料包傳給Fragment
fragment.setArguments(arguments);
return fragment;
}
}
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_settings">Settings</string>
<string name="app_name">電子拍賣</string>
<string name="welcome">歡迎使用電子拍賣系統</string>
<string name="hello_world">Hello world!</string>
<string name="user_name">使用者賬號:</string>
<string name="user_pass">使用者密碼</string>
<string name="login">登入</string>
<string name="cancel">取消</string>
<string name="hello">Hello World, Login!</string>
<string name="manage_kind">系統的所有物品種類</string>
<string name="manage_item">你當前的拍賣物品</string>
<string name="view_bid">你參與競標的物品</string>
<string name="choose_kind">請選擇一個物品的種類</string>
<string name="view_succ">瀏覽競得物品</string>
<string name="view_fail">瀏覽流拍物品</string>
<string name="item_list">當前種類的物品</string>
<string name="item_name">物品名:</string>
<string name="item_kind">物品種類:</string>
<string name="item_desc">物品描述:</string>
<string name="win_price">贏取價格:</string>
<string name="max_price">最高競價:</string>
<string name="remark">物品備註:</string>
</resources>
res/vaalues/dimens.xml<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="title_padding">10dp</dimen>
<dimen name="label_font_size">20dp</dimen>
<dimen name="sub_title_margin">20dp</dimen>
</resources>
執行效果:![](https://i.iter01.com/images/21e617fd71ef76d50c3c79eb2f3d03dd0d1cd44215f41e09a807367dc14bba1f.gif)
相關文章
- 拍賣商城體系定製開發的優勢
- 競拍秒購電商系統開發需求和功能架構分析架構
- 基於Java+SpringBoot+Mysql線上簡單拍賣競價拍賣競拍系統功能設計與實現三JavaSpring BootMySql
- 基於Java+SpringBoot+Mysql線上簡單拍賣競價拍賣競拍系統功能設計與實現十一JavaSpring BootMySql
- 盒格速賣系統電商軟體開發思路分享
- 使用Redis構建高併發高可靠的秒殺拍賣系統 - LuisRedisUI
- 電商新秀場——直播賣貨系統的特點及開發方案
- NFT數藏古玩拍賣平臺運營模式分析 | NFT數藏古玩拍賣平臺開發原始碼示例模式原始碼
- 拍賣商城體系的基本功能
- 電子元器件電子採購管理系統
- 直播賣貨系統開發,未來社交電商領域的發展是可期的
- 中國拍賣行業協會:2021中國文物藝術品拍賣市場統計年報行業
- 電子駐車系統(EPB)
- 商超智慧電子秤 收銀機系統定製開發介紹
- 電競系統開發技術詳情,掌趣電競系統開發案例(原始碼)原始碼
- 電商企業如何選擇erp系統開發?erp系統開發
- 電子招標採購系統之電子招標採購系統功能清單
- 狩獵者夾子機器人系統開發(案例開發),Hunter狩獵者夾子機器人系統開發原理詳細機器人
- 電商系統O2O商城系統開發
- MES車間電子看板系統
- 電子招投標系統EBD
- 非煤電子封條系統
- 礦山電子封條系統
- 信特賣新零售系統開發原始碼部署原始碼
- pancakeswap/uniswap夾子機器人系統開發方案丨Hunter狩獵者夾子機器人系統開發說明機器人
- 電子採購系統的優勢是什麼 常用的電子採購系統介紹
- 電子招標採購系統之Spring Cloud 電子招標採購系統功能清單SpringCloud
- 電商庫存系統的防超賣和高併發扣減方案
- iOS節拍器開發iOS
- NFT鑄造競拍交易平臺dapp系統開發合約部署詳情APP
- 電子採購系統,一站式電子採購平臺
- NFT藝術品鑄造交易競拍DAPP商城系統開發功能分析搭建APP
- 電子公文傳輸系統-進展二
- 3-電子支付技術與系統
- Java 版 電子招標採購系統Java
- 電子政務系統軟體評測
- 利用 SOLIDWORKS開發機械的電氣系統Solid
- Thinkphp開發的微信電商管理系統PHP
- 世界銀行使用.NET 7開發的免費電子問卷製作系統Survey Solution