安卓第四次作業——簡單校園二手交易APP


一、項目團隊

團隊成員

姓名:湯文濤 學號:1600802129 班級:計算機164班 博客地址:https://www.cnblogs.com/taotao01/
姓名:楊聖豪 學號:1600802101 班級:計算機163班 博客地址:http://www.cnblogs.com/ysh1998/
姓名:黃東強 學號:1600802083 班級:計算機163班 博客地址:http://www.cnblogs.com/hdq163/

二、APK鏈接

https://dev.tencent.com/u/xiaogui01/p/Android-TYH/git/blob/master/app/app-release.apk

APP運行錄屏

https://www.bilibili.com/video/av40161307/

三、代碼鏈接

https://git.dev.tencent.com/xiaogui01/Android-TYH.git

四、團隊項目介紹

4.1項目總體效果截圖






4.2實現的功能及其效果描述:

我們實現的功能有登錄、注冊、密碼修改、查看修改個人信息、上傳商品、查看我的發布、查看所有商品、查看某個商品的詳細信息、給商家留言這幾個主要的功能。
進入APP首先是登錄界面,沒有用戶名會提示先注冊,注冊時會驗證用戶名是否已存在;登錄時會驗證用戶名是否存在以及對應的密碼是否正確。
登陸后進入首頁,下邊的導航欄都可以跳轉實現,上面的四個商品分類導航欄用於查詢該分類的商品。
個人中心頁面里面的查詢個人信息、修改密碼、我的發布、關於我們都已實現;修改密碼會判斷原始密碼的正確性以及把新密碼修改到數據庫中。
發布頁面可以點擊上方的ImageButton來讀取手機上的圖片,填寫好商品的信息點擊發布按鈕就會把信息插入到商品表中,然后在主頁和我的發布頁面(會判斷當前登錄的用戶)顯示。
在首頁點擊商品會直接跳轉到該商品的詳細信息頁面,下方有留言區,可以留言。
目前已經實現了預期的大部分功能,有些小問題還在完善中。

五、關鍵代碼

5.1 修改用戶信息

usersave.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {//賬號userId,密碼passWord,姓名name,專業subject,電話phone,QQ號qq,地址address
  post_name=username.getText().toString();
  post_subject=usersubject.getText().toString();
  post_phone=userphone.getText().toString();
  post_qq=userqq.getText().toString();
  post_address=useraddress.getText().toString();
  ContentValues values=new ContentValues();
  values.put("name",post_name);
  values.put("subject",post_subject);
  values.put("phone",post_phone);
  values.put("qq",post_qq);
  values.put("address",post_address);
  saveValues(values);
  Toast.makeText(getApplicationContext(), "修改成功", Toast.LENGTH_SHORT).show();
  startActivity(intent);
  }
 });

5.2 驗證是否登錄

myshow.setOnClickListener(new View.OnClickListener() {
  @Override  
  public void onClick(View v) {
  if(a.equals("")||a==null){
    Toast.makeText(getApplicationContext(), "請先登錄!", Toast.LENGTH_SHORT).show();
    intent = new Intent(MyselfActivity.this,LoginMainActivity.class);
    startActivity(intent);
    }
  intent = new Intent(MyselfActivity.this,MyselfActivity.class);
  startActivity(intent);
  }
});

5.3 登錄獲取用戶ID,設置為全局變量

protected static String post_userid;

5.4 上傳商品信息插入到數據庫

Button fabu=(Button)findViewById(R.id.fabu);
        fabu.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                EditText title=(EditText)findViewById(R.id.m1_title);
                Spinner style=(Spinner)findViewById(R.id.m1_style);
                EditText price=(EditText)findViewById(R.id.m1_price);
                EditText phone=(EditText)findViewById(R.id.m1_phone);
                EditText nr=(EditText)findViewById(R.id.m1_nr);
                Date curDate = new Date(System.currentTimeMillis());
                String str = formatter.format(curDate);
                SQLiteDatabase db=dbHelper.getWritableDatabase();
                ContentValues values=new ContentValues();
                values.put("Id",25);
                values.put("title",title.getText().toString());
//              values.put("style", style.getTooltipText().toString());
                values.put("style", str);
                values.put("time",str.toString());
                values.put("price",price.getText().toString());
                values.put("phone",phone.getText().toString());
                values.put("nr",nr.getText().toString());
                db.insert("Sc_message",null,values);
                Intent intent=new Intent(MainActivity_m1.this,MainActivity.class);
                startActivity(intent);
            }
        });

5.5 把上傳數據庫中的信息顯示在我的發布列表中

MyDatabaseHelper mydb = new MyDatabaseHelper(this,"1600802129.db",null,1);
final SQLiteDatabase ddb = mydb.getWritableDatabase();
ListView listView = (ListView)findViewById(R.id.show_fabu);
Map<String, Object> item;
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
Cursor cursor = db.query("Sc_message",null,null,null,null,null,null,null);
if (cursor.moveToFirst()){
    while (!cursor.isAfterLast()){
        item = new HashMap<String, Object>();
        item.put("id",cursor.getInt(0));
        item.put("title",cursor.getString(1));
        item.put("nr",cursor.getBlob(6));
        item.put("style",cursor.getBlob(2));
        item.put("time",cursor.getString(3));
        item.put("price",cursor.getString(4));
        item.put("phone",cursor.getString(5));
        cursor.moveToNext();
        data.add(item);
    }
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.my_fabu, new String[] { "image", "title", "price", "pl", "ly" },
        new int[] { R.id.show_image, R.id.show_title, R.id.show_price, R.id.show_pl, R.id.show_view });
listView.setAdapter(simpleAdapter);

5.6顯示商品列表

 Dbtest dbtest = new Dbtest(this);
        final SQLiteDatabase db = dbtest.getWritableDatabase();
        ListView listView = (ListView)findViewById(R.id.listView);
        Map<String, Object> item;  // 列表項內容用Map存儲
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>(); // 列表
        Cursor cursor = db.query(TABLENAME,null,null,null,null,null,null,null); // 數據庫查詢
        if (cursor.moveToFirst()){
            while (!cursor.isAfterLast()){
                item = new HashMap<String, Object>();  // 為列表項賦值
                item.put("id",cursor.getInt(0));
                item.put("userid",cursor.getString(1));
                item.put("image",cursor.getBlob(6));
                item.put("title",cursor.getBlob(2));
                item.put("kind",cursor.getString(3));
                item.put("info",cursor.getString(4));
                item.put("price",cursor.getString(6));
                cursor.moveToNext();
                data.add(item); // 加入到列表中
            }
        }
        // 使用SimpleAdapter布局listview
        SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.listitem, new String[] { "image", "title", "kind", "info", "price" },
                new int[] { R.id.item_image, R.id.title, R.id.kind, R.id.info, R.id.price });
        listView.setAdapter(simpleAdapter);

5.7實現點擊相應列表項,跳到指定內容的頁面

        // 為列表項設置監聽器
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                intent = new Intent(main_page.this, item_info.class);
                intent.putExtra("id", data.get(position).get("id").toString()); // 獲取該列表項的key為id的鍵值,即商品的id,將其儲存在Bundle傳遞給打開的頁面
                startActivity(intent);
            }
        });
        Cursor cursor = db.query(TABLENAME,null,"id=?",new String[]{intent.getStringExtra("id")},null,null,null,null); // 根據接收到的id進行數據庫查詢
        Log.i("商品的id是",intent.getStringExtra("id"));
        if (cursor.moveToFirst()){
            while (!cursor.isAfterLast()){
                //imageView.setImageResource(R.drawable.buy_item1);
                title.setText(cursor.getString(2));
                price.setText(cursor.getString(5));
                info.setText(cursor.getString(4));
                cursor.moveToNext();
            }
        }

5.8實現圖片的上傳和即時顯示

        imageButton=(ImageButton)findViewById(R.id.m1_image);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(AddItem.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(AddItem.this, new
                            String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                } else {
                    //打開系統相冊
                    Intent intent = new Intent(Intent.ACTION_PICK,
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(intent, 1);
                }

            }
        });
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //獲取圖片路徑
        if (requestCode == 1 && resultCode == Activity.RESULT_OK && data != null) {
            Uri selectedImage = data.getData();
            String[] filePathColumns = {MediaStore.Images.Media.DATA};
            Cursor c = getContentResolver().query(selectedImage, filePathColumns, null, null, null);
            c.moveToFirst();
            int columnIndex = c.getColumnIndex(filePathColumns[0]);
            String imagePath = c.getString(columnIndex);
            showImage(imagePath);
            c.close();
        }
    }
    //加載圖片
    private void showImage(String imaePath) {
        Bitmap bm = BitmapFactory.decodeFile(imaePath);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        image = baos.toByteArray();
        imageButton.setImageBitmap(bm);
    }

5.9實現讀取數據庫中的圖片並將其插入到列表中

        byte[] imagedata;
        Bitmap imagebm;
        imagedata = cursor.getBlob(6);
        imagebm = BitmapFactory.decodeByteArray(imagedata, 0, imagedata.length);
        item.put("image",imagebm);

        SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.listitem, new String[] { "image", "title", "kind", "info", "price" },
                new int[] { R.id.item_image, R.id.title, R.id.kind, R.id.info, R.id.price });
        simpleAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
            @Override
            public boolean setViewValue(View view, Object data, String textRepresentation) {
                if(view instanceof ImageView  && data instanceof Bitmap){
                    ImageView iv = (ImageView)view;
                    iv.setImageBitmap( (Bitmap)data );
                    return true;
                }else{
                    return false;
                }
            }
        });
        listView.setAdapter(simpleAdapter);

六、評選其他團隊APK

第一名:李凱、季軒石組
實現了一個添加計划並打卡的app,界面簡潔美觀,交互感很好。
優點:app實現了基本的添加計划修改計划並打卡等功能,並在日期輸入時調起了系統日歷,提高了交互性。
缺點:app並沒有用戶登錄功能,可能是考慮只在單機上使用;而且提醒功能沒有,點擊“打卡”選項會閃退。
如果是我來做:如果我來參與這個項目的話,我應該會考慮加入后台提醒的功能,比如添加了某個時刻后,在到時間時手機系統給出提醒

第二名:洪居興,鄧旺,李洪岩組
制作了一個旅游方面的APP,實現了登錄注冊、手機發驗證碼、查看地圖、查看部分自帶的景點信息描述,總體上效果不錯。
優點:實現了手機驗證碼這個功能,能調用第三方發送驗證保證了安全性;其次,實現了查詢地圖的功能,通過調用百度地圖來實時確定自己的位置,完成了旅游APP較大的功能,很不錯。
缺點:界面比較簡單,而且地圖定位時定位的不太准確,有一定誤差。查詢功能也沒有實現,只能查看APP上已有的風景區,技術尚且不能滿足客戶需求,但后期可以繼續來完善。
如果是我來做:如果是我來做的話,我會主要來做風景區查詢這一塊,通過跳轉其它瀏覽器來查詢地方返回一些數據,手機驗證碼的話我可能不會先去做。其實在這幾天時間他們能做出這些已經很不錯啦。

第三名:劉宇瑩、孟鑫菲組
制作了一個電子拍賣的APP,實現了服務器端和客戶端。
優點:項目實現了用戶的登錄、注冊、查看所有物品種類、查看用戶競拍的物品、查看用戶的拍賣物品,添加用戶拍賣物品等功能;實現的功能比較完善。在項目中設計了服務器端和安卓端。這個很好
缺點:部分功能沒有實現,而且登錄的時候時不時會閃退,用戶體驗感較差。
如果是我來做:如果我參與這個項目我會優先解決閃退問題。

第四名:段嗣躍,陳素偉組
制作了一個二手交易平台APP,實現了注冊登錄查詢功能
優點:一些功能實現的比較好,如注冊之后可以直接點擊登錄,保留了注冊時賬號密碼。發布界面實現了圖片上傳功能,並能顯示出來。界面總體上比較美觀。
缺點:APP功能不太完善,有的界面沒有實際功能,只是靜態頁面,APP有待完善,例如消息頁面能查看交易與互動信息。
如果是我來做:如果我來做我會主要實現上傳和查詢界面,增加用戶對商品評論功能。

第五名:沈順文組
制作了一個代碼方面的簡單APP--代碼殺,實現了基本的功能,內容比較多。
優點:界面還可以,功能板塊考慮的比較全面,比較符合實際情況,而且還是自己一個人獨自完成的,這點很棒。
缺點:部分功能沒有實現,查詢問題還是只能查詢APP自帶的一些內容,具有局限性。同樣,APP上也存在閃退問題沒解決。
如果是我來做:如果我參與這個項目的話,我會把中的放在查詢功能上。

七、團隊成員遇到的問題及解決的方法

成員1:湯文濤

問題一:如何把上傳數據庫中的信息依次顯示在查看發布列表里面
解決方法:通過網上查詢解決辦法,我先寫了一個商品信息模板,在發布列表對應的Java文件中來讀取數據庫中的信息,用一個新的列表存儲,在調用模板傳參到顯示頁面中。
問題二:在把發布商品信息傳到數據庫時,Spinner中的選項無法直接獲取插入到數據庫
解決方法:在對應的Java文件中開頭定義一個新的String對象,添加Spinner響應事件,在響應中用定義的String對象來接收選項值,再在插入數據時直接插入這個String對象。
問題三:如何上傳相片
解決方法:通過添加ImageButton響應按鈕,點擊獲取SD卡權限從手機自帶的圖庫中添加照片(但是只能添加一張),然后在點擊發布按鈕的響應中用BLOB類型插入到數據庫中。

成員2:楊聖豪

問題一:如何實現圖文列表顯示
解決方法:使用SimpleAdapter類,為listview設置一個模板布局xml文件,代表listview中每個列表項的布局樣式,使用Map儲存列表項中各個屬性,將多個Map儲存在List中,最后調用SimpleAdapter類構造函數構造其對象布局各個列表項
問題二:如何實現底部導航欄置底
解決方法:因為linerlayout布局是垂直依次排列的,導航欄作為最后一個組件默認是不會置底的,所以需要設置底部導航欄和導航欄上方的組件高度為0,通過設置兩個組件的權重來控制導航欄置底。
問題三:如何實現點擊相應列表項,跳到指定內容的頁面
解決方法:因為每個列表項都是Map類型的對象,獲取其鍵為"id"的值,通過Bundle傳值給跳轉到的頁面,在頁面中根據id進行數據庫查詢,查到該id對應的商品信息,顯示在頁面中
問題四:如何實現圖片的上傳和即時顯示
解決方法:調用系統相冊,獲取圖片的路徑,編碼成bitmap格式,在相應的imageview / imagebutton處調用setImageBitmap函數顯示圖片
問題五:如何讀取數據庫中的圖片並將其插入到列表中
解決方法:調用getBlob后,使用BitmapFactory.decodeByteArray進行解碼,因為使用了listview,不能直接setImageBitmap,方法是調用過SimpleAdapter構造函數布局好listview之后,再為SimpleAdapter對象設置setViewBinder,對於listview中需要設置圖片的view調用setImageBitmap函數。

成員3:黃東強

問題一:程序頁面Intent進行跳轉時會程序無法運行
解決方法:意外終止,多次調試,發現結果為,未在Mainfest.xml中配置Activity
問題二:用戶未登錄卻能訪問用戶信息頁面和修改密碼頁面
解決方法:先驗證全局變量用戶Id是否為空,若為空則彈出用戶未登錄,跳轉至登錄頁面
問題三:如何登錄后獲取用戶ID
解決方法:設置為全局變量,使各個Activity都能訪問到它。百度上的設置全局變量有2中方式,一種是新建Application類來存放userId,一種是新建java類來存放userId,按其方法,會導致userId為空時,程序意外終止無法進行。最后設置一個靜態全局變量static userid來存放數據,其他Activity可以正常訪問並修改。

八、項目成員分工及打分

姓名 分工 比例 分數
湯文濤 上傳、我的發布、留言的頁面設計及功能實現 33% 10
楊聖豪 商品信息、主頁、商品分類的頁面設計及功能實現,整合項目 34% 10
黃東強 登錄、注冊、個人中心的頁面設計及功能實現 33% 10
注:因為開始我們是分開各自先寫自己那一部分,但在整合時是整合在一個人的電腦上,由一個人上傳完整能運行的代碼,各個功能模塊就是按上面的分工來進行的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM