Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) |
Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) บทความนี้เกี่ยวกับระบบ Vote และ Rating และเป็นภาพต่อของ บทความที่ 1 และ บทความที่ 2 แต่จะเพิ่มความสามารถที่จะป้องกันการ Vote ซ้ำ โดยจะใช้ระบบสมาชิกจะต้อง Login ก่อนที่จะเข้าไป Vote และสมาชิกสามารถ Vote ได้คนล่ะ 1 Item ต่อ 1 ครั้ง และเมื่อแต่ล่ะสมาชิกได้โหวตเรียบร้อยแล้ว จะมีการแสดง Rating Point ซึ่งจะเป็นค่าเฉลี่ย (Average) คะแนนที่ได้จริง ๆ โดยสูตรการหาค่าเฉลี่ยของคะแนน Raing คือ
ค่าเฉลี่ย (Average) = [ผลรวมจำนวนคะแนนทั้งหมดของแต่ล่ะรายการ] / [จำนวนผู้โหวดของรายการนั้นๆ]
เช่น
นาย A โหวต = 4
นาย B โหวด = 3
นาย C โหวด = 2
ค่าเฉลี่ยจะเท่ากับ = (4+3+2) / 3 = 3
เมื่อได้ค่าเฉลี่ย(Average) นี้แล้วก็จะนำไปแสดงผลบน RatingBar ของ ListView
ขั้นตอนก็คือ จะสร้างตารางทั้งหมดขึ้นมา 3 table คือ
- images (เก็ยรายชื่อรูปภาพที่จะแสดงผลบน ListView)
- member (เก็บรายชื่อสมาชิก ซึ่งประกอบด้วย Username และ Password ในการ Login และข้อมูลอื่น ๆ)
- rating (เก็บรายการ Rating ของแต่ล่ะ Item ที่สมาชิกโหวตเข้ามา โดยจัดเก็บ 1 คนต่อ 1 item)
กระบวนการทำงานก็คือ สมาชิกจะ Login เข้าสู่ Application โดยตรวจสอบจากตาราง member และหลังจาก Login ผ่านเรียบร้อยแล้ว จะแสดงข้อมูลรายการรูปภาพบน ListView และสมาชิกสามารถเลือกแต่ล่ะรายการเพื่อโหวตให้คะแนน และหลังจากที่โหวตให้คะแนนเรียบร้อยแล้ว ตะแนนจะถูกส่งไป Insert ที่ตาราง rating บน Web Server โดยจัดเก็บข้อมูลทุก ๆ รายการที่โหวต และสมาชิกจะสามารถโหวด 1 รายการต่อ 1 ครั้งเท่านั้น และทุก ๆ ครั้งที่มีการโหวต ในฝั่งของ Web Server จะมีการ Update คะแนนค่าเฉลี่ยนไปยังตาราง images ด้วยทุกครั้ง เพื่อจะได้นำมาข้อมูลเหล่านี้มาแสดงผลบน ListView
บทความที่เกี่ยวข้องกับการ Vote และ RatingBar ตัวอย่างที่ 1 และที่ 2
เพื่อความเข้าใจควรอ่าน 2 บทความนี้ก่อน
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
ในการเขียน Android เพื่อติดต่อกับ Internet จะต้องกำหนด Permission ในส่วนนี้ด้วยทุกครั้ง
Web Server (PHP and MySQL)
MySQL Database
member
CREATE TABLE `member` (
`MemberID` int(2) NOT NULL auto_increment,
`Username` varchar(50) NOT NULL,
`Password` varchar(50) NOT NULL,
`Name` varchar(50) NOT NULL,
`Tel` varchar(50) NOT NULL,
`Email` varchar(150) NOT NULL,
PRIMARY KEY (`MemberID`),
UNIQUE KEY `Username` (`Username`),
UNIQUE KEY `Email` (`Email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
--
-- Dumping data for table `member`
--
INSERT INTO `member` VALUES (1, 'weerachai', 'weerachai@1', 'Weerachai Nukitram', '0819876107', '[email protected]');
INSERT INTO `member` VALUES (2, 'adisorn', 'adisorn@2', 'Adisorn Bunsong', '021978032', '[email protected]');
INSERT INTO `member` VALUES (3, 'surachai', 'surachai@3', 'Surachai Sirisart', '0876543210', '[email protected]');
ตารางสำหรับเก็บ User และ Password ในการ Login ของ Member
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-01.jpg?v=1001)
images
CREATE TABLE `images` (
`ImageID` int(11) NOT NULL auto_increment,
`ImageName` varchar(50) NOT NULL,
`ImagePath_Thumbnail` varchar(150) NOT NULL,
`ImagePath_FullPhoto` varchar(150) NOT NULL,
`Rating` float NOT NULL,
PRIMARY KEY (`ImageID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
--
-- Dumping data for table `images`
--
INSERT INTO `images` VALUES (1, 'Image 1', 'https://www.thaicreate.com/android/img1_thum.jpg', 'https://www.thaicreate.com/android/img1_full.jpg', 0);
INSERT INTO `images` VALUES (2, 'Image 2', 'https://www.thaicreate.com/android/img2_thum.jpg', 'https://www.thaicreate.com/android/img2_full.jpg', 0);
INSERT INTO `images` VALUES (3, 'Image 3', 'https://www.thaicreate.com/android/img3_thum.jpg', 'https://www.thaicreate.com/android/img3_full.jpg', 0);
INSERT INTO `images` VALUES (4, 'Image 4', 'https://www.thaicreate.com/android/img4_thum.jpg', 'https://www.thaicreate.com/android/img4_full.jpg', 0);
INSERT INTO `images` VALUES (5, 'Image 5', 'https://www.thaicreate.com/android/img5_thum.jpg', 'https://www.thaicreate.com/android/img5_full.jpg', 0);
INSERT INTO `images` VALUES (6, 'Image 6', 'https://www.thaicreate.com/android/img6_thum.jpg', 'https://www.thaicreate.com/android/img6_full.jpg', 0);
![](/images/adv.jpg)
ตารางสำหรับเก็บ Gallery Images ที่จะแสดงผลบน ListView และใน ฟิวด์สุดท้ายจะเห็นว่าจะมีฟิวด์ชื่อว่า Rating ฟิวด์นี้มีไว้สำหรับเก็บค่าเฉลี่ยของการโหวตดทั้งหมด ของรายการนั้น ๆ
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-03.jpg?v=1001)
rating
CREATE TABLE `rating` (
`RatingID` int(11) NOT NULL auto_increment,
`ImageID` int(11) NOT NULL,
`MemberID` int(2) NOT NULL,
`RatingPoint` float NOT NULL,
PRIMARY KEY (`RatingID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
เก็บรายละเอียดการ Vote ของสมาชิกแต่ล่ะคน
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-02.jpg?v=1001)
checkLogin.php (ไฟล์สำหรับตรวจสอบการ Login)
<?php
$objConnect = mysql_connect("localhost","root","root");
$objDB = mysql_select_db("mydatabase");
//$_POST["strUser"] = "weerachai"; // for Sample
//$_POST["strUser"] = "weerachai@1"; // for Sample
$strUsername = $_POST["strUser"];
$strPassword = $_POST["strPass"];
$strSQL = "SELECT * FROM member WHERE 1
AND Username = '".$strUsername."'
AND Password = '".$strPassword."'
";
$objQuery = mysql_query($strSQL);
$objResult = mysql_fetch_array($objQuery);
$intNumRows = mysql_num_rows($objQuery);
if($intNumRows==0)
{
$arr['StatusID'] = "0";
$arr['MemberID'] = "0";
$arr['Name'] = "";
$arr['Error'] = "Incorrect Username and Password";
}
else
{
$arr['StatusID'] = "1";
$arr['MemberID'] = $objResult["MemberID"];
$arr['Name'] = $objResult["Name"];
$arr['Error'] = "";
}
/**
$arr['StatusID'] // (0=Failed , 1=Complete)
$arr['MemberID'] // MemberID
$arr['Name'] // Member Name
$arr['Error'] // Error Message
*/
mysql_close($objConnect);
echo json_encode($arr);
?>
getGallery.php (ไฟล์สำหรับแสดง Gallery image บน ListView)
<?php
$objConnect = mysql_connect("localhost","root","root");
$objDB = mysql_select_db("mydatabase");
$strSQL = "SELECT * FROM images WHERE 1 ";
$objQuery = mysql_query($strSQL);
$intNumField = mysql_num_fields($objQuery);
$resultArray = array();
while($obResult = mysql_fetch_array($objQuery))
{
$arrCol = array();
for($i=0;$i<$intNumField;$i++)
{
$arrCol[mysql_field_name($objQuery,$i)] = $obResult[$i];
}
array_push($resultArray,$arrCol);
}
mysql_close($objConnect);
echo json_encode($resultArray);
?>
updateRating.php (ไฟล์สำหรับ Update Rating ที่ถูกส่งมาจาก Android Client)
<?php
//$_POST["ImageID"] = "1"; // ImageID
//$_POST["MemberID"] = "1"; // MemberID
//$_POST["ratingPoint"] = "3.5"; // ratingPoint
$objConnect = mysql_connect("localhost","root","root");
$objDB = mysql_select_db("mydatabase");
// Check Duplicate
$strSQL = "SELECT * FROM rating WHERE 1 AND ImageID = '".$_POST["ImageID"]."'
AND MemberID = '".$_POST["MemberID"]."' ";
$objQuery = mysql_query($strSQL);
$obResult = mysql_fetch_array($objQuery);
if($obResult)
{
$arr['StatusID'] = "0";
$arr['Error'] = "Duplicate Vote!";
$arr['Rating'] = "0";
mysql_close($objConnect);
echo json_encode($arr);
exit();
}
/*** Insert rating ***/
$strSQL = "INSERT INTO rating (ImageID,MemberID,RatingPoint)
VALUES (
'".$_POST["ImageID"]."',
'".$_POST["MemberID"]."',
'".$_POST["ratingPoint"]."'
) ";
$objQuery = mysql_query($strSQL);
/*** Update Rating Average ***/
$strSQL = " UPDATE images SET
Rating = (SELECT AVG(RatingPoint) FROM rating WHERE ImageID = '".$_POST["ImageID"]."')
WHERE ImageID = '".$_POST["ImageID"]."' ";
$objQuery = mysql_query($strSQL);
// Return New Rating Point
$strSQL = "SELECT * FROM images WHERE 1 AND ImageID = '".$_POST["ImageID"]."' ";
$objQuery = mysql_query($strSQL);
$obResult = mysql_fetch_array($objQuery);
if($obResult)
{
$arr['StatusID'] = "1";
$arr['Error'] = "";
$arr['Rating'] = $obResult["Rating"];
}
/**
$arr['StatusID'] // (0=Failed , 1=Complete)
$arr['Error'] // Error Message
$arr['Rating'] // New Rating Point
*/
mysql_close($objConnect);
echo json_encode($arr);
?>
ในไฟล์นี้หน้าที่สำคัญก็คือ รับค่าจากการ Vote ของสมาชิกแต่ล่ะคน และบันทึกรายการลงในตารางของ rating และ อัพเดดค่าเฉลี่ยของการโหวตไปยังตาราง images
Android Project
โครงสร้างของไฟล์ทั้งหมด
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-04.jpg?v=1001)
ในตัวอย่างนี้มีการใช้ Custom RatingBar ซึ่งจะสร้าง Style ขึ้นมามีรายละเอียดดังนี้
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-custom-ratingbar-01.jpg?v=1001)
Icons รูปภาพ ที่จะใช้แสดงบน Custom RatingBar
/res/drawable/ratingstars.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+android:id/background"
android:drawable="@drawable/star_empty" />
<item android:id="@+android:id/secondaryProgress"
android:drawable="@drawable/star_empty" />
<item android:id="@+android:id/progress"
android:drawable="@drawable/star_full" />
</layer-list>
สร้าง Style อยู่บนไฟล์ ratingstars.xml
/values/string.xml
<style name="styleRatingBar" parent="@android:style/Widget.RatingBar">
<item name="android:progressDrawable">@drawable/ratingstars</item>
<item name="android:minHeight">22dip</item>
<item name="android:maxHeight">22dip</item>
</style>
เพิ่มคำสั่งชุดนี้ลงใน string.xml
รายละเอียดเพิ่มเติมของ Custom RatingBar สามารถอ่านได้ที่นี่
ออกแบบ XML Layout และ Java ดังนี้
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-05.jpg?v=1001)
activity_main.xml
<RelativeLayout 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" >
<Button
android:id="@+id/btnlogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="101dp"
android:text="Login" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:text="Welcome to My App"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-06.jpg?v=1001)
activity_login.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_login"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/txtTitleUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="7dp"
android:text="Username : " />
<EditText
android:id="@+id/txtUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/txtTitleUsername"
android:layout_centerHorizontal="true"
android:layout_marginTop="7dp"
android:ems="10" >
<requestFocus />
</EditText>
<TextView
android:id="@+id/txtTitlePassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/txtUsername"
android:layout_centerHorizontal="true"
android:layout_marginTop="7dp"
android:text="Password : " />
<EditText
android:id="@+id/txtPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/txtUsername"
android:layout_below="@+id/txtTitlePassword"
android:layout_marginTop="7dp"
android:ems="10"
android:inputType="textPassword" />
</RelativeLayout>
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-07.jpg?v=1001)
activity_vote.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tableLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="ListView and Rating : "
android:layout_span="1"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Member Name" />
</TableRow>
<View
android:layout_height="1dip"
android:background="#CCCCCC" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1">
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
<View
android:layout_height="1dip"
android:background="#CCCCCC" />
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="By.. ThaiCreate.Com" />
</LinearLayout>
</TableLayout>
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-08.jpg?v=1001)
activity_column.xml
<TableLayout android:id="@+id/tableLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/ColImgPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/ColImgID"
android:text="Column 1" />
<TextView
android:id="@+id/ColImgName"
android:text="Column 2" />
<RatingBar
android:id="@+id/ColratingBar"
style="@style/styleRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-09.jpg?v=1001)
activity_dialog.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_dialog"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp" />
<RatingBar
android:id="@+id/ratingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/imageView"
android:layout_centerHorizontal="true"
android:layout_marginTop="22dp" />
</RelativeLayout>
MainActivity.java
package com.myapp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.Bundle;
import android.os.StrictMode;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Permission StrictMode
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
final AlertDialog.Builder popDialog = new AlertDialog.Builder(this);
final AlertDialog.Builder ad = new AlertDialog.Builder(this);
final LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
// btnlogin
Button btnLogin = (Button) findViewById(R.id.btnlogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final View Viewlayout = inflater.inflate(R.layout.activity_login,
(ViewGroup) findViewById(R.id.layout_login));
popDialog.setIcon(android.R.drawable.btn_star_big_on);
popDialog.setTitle("Input User and Password ");
popDialog.setView(Viewlayout);
// Button OK
popDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
// txtUsername and Password (Dialog)
EditText user = (EditText) Viewlayout.findViewById(R.id.txtUsername);
EditText pass = (EditText) Viewlayout.findViewById(R.id.txtPassword);
String url = "https://www.thaicreate.com/android/myphp/checkLogin.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("strUser", user.getText().toString()));
params.add(new BasicNameValuePair("strPass", pass.getText().toString()));
/** Get result from Server (Return the JSON Code)
* StatusID = ? [0=Failed,1=Complete]
* MemberID = ? [Eg : 1]
* Name = ? [Eg : Weerachai Nukitram]
* Error = ? [On case error return custom error message]
*
* Eg Login Failed = {"StatusID":"0","MemberID":"0","Name":"","Error":"Incorrect Username and Password"}
* Eg Login Complete = {"StatusID":"1","MemberID":"2","Name":"Weerachai Nukitram","Error":""}
*/
String resultServer = getHttpPost(url,params);
/*** Default Value ***/
String strStatusID = "0";
String strMemberID = "0";
String strName = "0";
String strError = "Unknow Status!";
JSONObject c;
try {
c = new JSONObject(resultServer);
strStatusID = c.getString("StatusID");
strMemberID = c.getString("MemberID");
strName = c.getString("Name");
strError = c.getString("Error");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Prepare Login
if(strStatusID.equals("0"))
{
// Dialog
ad.setTitle("Error! ");
ad.setIcon(android.R.drawable.btn_star_big_on);
ad.setPositiveButton("Close", null);
ad.setMessage(strError);
ad.show();
}
else
{
Toast.makeText(MainActivity.this, "Login OK", Toast.LENGTH_SHORT).show();
Intent newActivity = new Intent(MainActivity.this,VoteActivity.class);
newActivity.putExtra("sMemberID", strMemberID);
newActivity.putExtra("sName", strName);
startActivity(newActivity);
}
}
})
// Button Cancel
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel();
}
});
popDialog.create();
popDialog.show();
}
});
}
public String getHttpPost(String url,List<NameValuePair> params) {
StringBuilder str = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Status OK
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
str.append(line);
}
} else {
Log.e("Log", "Failed to download result..");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str.toString();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
VoteActivity.java
package com.myapp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
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.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Menu;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
public class VoteActivity extends Activity {
public static final int DIALOG_DOWNLOAD_JSON_PROGRESS = 0;
private ProgressDialog mProgressDialog;
ArrayList<HashMap<String, Object>> MyArrList;
ListView lstView1;
public String sMemberID;
public String sMemberName;
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vote);
// Permission StrictMode
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Intent intent= getIntent();
sMemberID = intent.getStringExtra("sMemberID");
sMemberName = intent.getStringExtra("sName");
// Display Member Name
TextView txtName = (TextView)findViewById(R.id.txtName);
txtName.setText(sMemberName);
// Download JSON File
new DownloadJSONFileAsync().execute();
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_JSON_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading.....");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setCancelable(true);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
// Show All Content
public void ShowAllContent()
{
// listView1
lstView1 = (ListView)findViewById(R.id.listView1);
lstView1.setAdapter(new ImageAdapter(VoteActivity.this,MyArrList));
}
public class ImageAdapter extends BaseAdapter
{
private Context context;
private ArrayList<HashMap<String, Object>> MyArr = new ArrayList<HashMap<String, Object>>();
public ImageAdapter(Context c, ArrayList<HashMap<String, Object>> myArrList)
{
// TODO Auto-generated method stub
context = c;
MyArr = myArrList;
}
public int getCount() {
// TODO Auto-generated method stub
return MyArr.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_column, null);
}
// ColImage
ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
imageView.getLayoutParams().height = 80;
imageView.getLayoutParams().width = 80;
imageView.setPadding(10, 10, 10, 10);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
try
{
imageView.setImageBitmap((Bitmap)MyArr.get(position).get("ImageThumBitmap"));
} catch (Exception e) {
// When Error
imageView.setImageResource(android.R.drawable.ic_menu_report_image);
}
// Click on Image
imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String strImageID = MyArr.get(position).get("ImageID").toString();
String strImageName = MyArr.get(position).get("ImageName").toString();
String strCurrentRating = MyArr.get(position).get("Rating").toString();
ShowDialogVote(position, strImageID,
strImageName, strCurrentRating,
MyArr.get(position).get("ImagePathFull").toString()); // Click Show Dialog Vote
}
});
// ColImgID
TextView txtImgID = (TextView) convertView.findViewById(R.id.ColImgID);
txtImgID.setPadding(5, 0, 0, 0);
txtImgID.setText("ID : " + MyArr.get(position).get("ImageID").toString());
// ColImgName
TextView txtPicName = (TextView) convertView.findViewById(R.id.ColImgName);
txtPicName.setPadding(5, 0, 0, 0);
txtPicName.setText("Name : " + MyArr.get(position).get("ImageName").toString());
// ColratingBar
RatingBar Rating = (RatingBar) convertView.findViewById(R.id.ColratingBar);
Rating.setPadding(10, 0, 0, 0);
Rating.setEnabled(false);
Rating.setRating(Float.valueOf(MyArr.get(position).get("Rating").toString()));
return convertView;
}
}
// Show Dialog Vote
public void ShowDialogVote(final int position, final String strImageID,
String strImageName,final String strCurrentRating,String FullImagePath)
{
final AlertDialog.Builder popDialog = new AlertDialog.Builder(this);
final AlertDialog.Builder adb = new AlertDialog.Builder(this);
final LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
final View Viewlayout = inflater.inflate(R.layout.activity_dialog,
(ViewGroup) findViewById(R.id.layout_dialog));
final ImageView image = (ImageView)Viewlayout.findViewById(R.id.imageView); // imageView
image.setImageBitmap((Bitmap)loadBitmap(FullImagePath));
final RatingBar rating = (RatingBar)Viewlayout.findViewById(R.id.ratingBar); // ratingBar
rating.setMax(5);
rating.setNumStars(5);
popDialog.setIcon(android.R.drawable.btn_star_big_on);
popDialog.setTitle("Vote!! (" + strImageName + ") ");
popDialog.setView(Viewlayout);
// Button OK
popDialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Save Vote
String url = "https://www.thaicreate.com/android/updateRating.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("ImageID", strImageID));
params.add(new BasicNameValuePair("MemberID", sMemberID));
params.add(new BasicNameValuePair("ratingPoint", String.valueOf(rating.getRating())));
String resultServer = getHttpPost(url,params);
/** Get result from Server (Return the JSON Code)
* StatusID = ? [0=Failed,1=Complete]
* Error = ? [On case error return custom error message]
* Rating = ? [New Reting Point from Server]
*
* Eg Save Failed = {"StatusID":"0","Error":"Not Update Data!","Rating":"0"}
* Eg Save Complete = {"StatusID":"1","Error":"","Rating":"3.5"}
*/
/*** Default Value ***/
String strStatusID = "0";
String strError = "Unknow Status!";
String strRatingPoint = strCurrentRating;
JSONObject c;
try {
c = new JSONObject(resultServer);
strStatusID = c.getString("StatusID");
strError = c.getString("Error");
strRatingPoint = c.getString("Rating"); // New Rating from Server
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Prepare Save Data
if(strStatusID.equals("0"))
{
adb.setMessage(strError);
adb.show();
}
else
{
Log.d("strRatingPoint",strRatingPoint);
UpdateNewRatingPoint(position,strRatingPoint); // Update New Rating Point to ListView (By Row Item)
// Show Toast
Toast.makeText(VoteActivity.this, "Vote Finished (Point : " + rating.getRating() + ")", Toast.LENGTH_LONG).show();
}
dialog.dismiss();
}
})
// Button Cancel
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
popDialog.create();
popDialog.show();
}
// Update New Rating to ListView
private void UpdateNewRatingPoint(int position,String newRatingPoint){
View v = lstView1.getChildAt(position - lstView1.getFirstVisiblePosition());
// Update RatingBar
RatingBar rating = (RatingBar)v.findViewById(R.id.ColratingBar);
rating.setEnabled(true); // Enabled
rating.setRating(Float.valueOf(newRatingPoint));
rating.setEnabled(false); // False
}
// Download JSON in Background
public class DownloadJSONFileAsync extends AsyncTask<String, Void, Void> {
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
}
@Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
String url = "https://www.thaicreate.com/android/getGallery.php";
JSONArray data;
try {
data = new JSONArray(getJSONUrl(url));
MyArrList = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map;
for(int i = 0; i < data.length(); i++){
JSONObject c = data.getJSONObject(i);
map = new HashMap<String, Object>();
map.put("ImageID", (String)c.getString("ImageID"));
map.put("ImageName", (String)c.getString("ImageName"));
// Thumbnail Get ImageBitmap To Object
map.put("ImagePathThum", (String)c.getString("ImagePath_Thumbnail"));
map.put("ImageThumBitmap", (Bitmap)loadBitmap(c.getString("ImagePath_Thumbnail")));
// Full (for View Popup)
map.put("ImagePathFull", (String)c.getString("ImagePath_FullPhoto"));
map.put("Rating", (String)c.getString("Rating"));
MyArrList.add(map);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void unused) {
ShowAllContent(); // When Finish Show Content
dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
}
}
// get Http Post
public String getHttpPost(String url,List<NameValuePair> params) {
StringBuilder str = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Status OK
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
str.append(line);
}
} else {
Log.e("Log", "Failed to download result..");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str.toString();
}
/*** Get JSON Code from URL ***/
public String getJSONUrl(String url) {
StringBuilder str = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Download OK
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
str.append(line);
}
} else {
Log.e("Log", "Failed to download file..");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str.toString();
}
/***** Get Image Resource from URL (Start) *****/
private static final String TAG = "Image";
private static final int IO_BUFFER_SIZE = 4 * 1024;
public static Bitmap loadBitmap(String url) {
Bitmap bitmap = null;
InputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copy(in, out);
out.flush();
final byte[] data = dataStream.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
//options.inSampleSize = 1;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);
} catch (IOException e) {
Log.e(TAG, "Could not load Bitmap from: " + url);
} finally {
closeStream(in);
closeStream(out);
}
return bitmap;
}
private static void closeStream(Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
android.util.Log.e(TAG, "Could not close stream", e);
}
}
}
private static void copy(InputStream in, OutputStream out) throws IOException {
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
/***** Get Image Resource from URL (End) *****/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
เพิ่ม VoteActivity ลงในไฟล์ AndroidManifest.xml
AndroidManifest.xml
<activity
android:name=".VoteActivity"
android:theme="@style/AppTheme"
android:screenOrientation="portrait"
android:label="@string/title_activity_main" />
Screenshot
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-10.jpg?v=1001)
แสดงหน้าแรกของ Application ของ Android ที่ทำงานผ่าน Emulator ให้คลิกที่ Login
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-11.jpg?v=1001)
แสดง Popup Dialog สำหรับการ Login ด้วย Username และ Password เข้าสู่หน้าจอการโหวต
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-12.jpg?v=1001)
หลังจาก Member Login ผ่านเรียบร้อยแล้ว ก็จะเข้าสู่หน้าจอรายการ Image Gallery โดยรอซะครู่ โปรแกรมกำลังโหลดจ้อมูลจาก Server
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-13.jpg?v=1001)
แสดงรายการข้อมูล สังเกตุว่าบน Header จะแสดงชื่อสมาชิกที่กำลัง Login อยู่ในขณะนั้น ให้คลิกรายการเพื่อโหวตข้อมูล
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-14.jpg?v=1001)
โดยเลือกที่ 4 ดาว จากนั้นเลือก OK (สมาชิกจะไม่สามารถโหวดซ้ำได้ ถ้าโหวดซ้ำโปรแกรมจะแสดงข้อความเตือนว่า Duplicate Vote!)
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-15.jpg?v=1001)
เมื่อกลับมาที่ ListView จะเห็นว่าได้คะแนน 4 ดาว
ทดสอบการ Login ด้วยสมาชิกคนอื่น
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-16.jpg?v=1001)
หลังจากที่ Login ด้วยสมาชิกอื่น ทดสอบการโหวดให้คลิกที่ Item เดิมที่มี Point อยู่แล้ว ตอนนี้จะเท่ากับ 4 ดาว
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-17.jpg?v=1001)
ให้คะแนน 1 ดาว แล้วเลือก OK
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-18.jpg?v=1001)
เมื่อกลับมาที่ ListView จะเห็นว่าได้คะแนนแค่ 2.5 ดาว (เพราะคนแรกให้ 4 คนที่สองให้ 1 ค่าเฉลี่ยจะเท่ากับ (4+1)/2 = 2.5)
![Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating) Android Rating (Vote) and ListView Part 2 (Member Login and Average Rating)](https://www.thaicreate.com/upload/tutorial/android-ratingbar-listview-part2-19.jpg?v=1001)
ตารางจัดเก็บและการคิดค่าเฉลี่ยนของ Rating
Download Code ได้จากส่วนล่างของบทความ
.
|
ช่วยกันสนับสนุนรักษาเว็บไซต์ความรู้แห่งนี้ไว้ด้วยการสนับสนุน Source Code 2.0 ของทีมงานไทยครีเอท
|
|
|
By : |
ThaiCreate.Com Team (บทความเป็นลิขสิทธิ์ของเว็บไทยครีเอทห้ามนำเผยแพร่ ณ เว็บไซต์อื่น ๆ) |
|
Score Rating : |
![](/images/resource/startrue.gif) ![](/images/resource/startrue.gif) |
|
|
Create/Update Date : |
2012-08-26 12:22:01 /
2017-03-26 22:36:50 |
|
Download : |
|
|
Sponsored Links / Related |
|
|
|
|
|
|
|