让我们看一下工作的屏幕截图,以便更好地理解问题:
Thumbnail 1.png
],如下图所示:
ListView
时,得到这个 - 这就是真正的痛苦,正如您所看到的Thumbnail 7
,我没有点击它:
ListView
,得到一些东西 - 这让我感到恼火,对Thumbnail 2
同样如此,我没有碰到那个:
我认为that's enough
向您解释,我想要做什么,发生什么和 我遇到了问题
现在轮到让我知道解决方案,我该如何解决这个问题?
一些说明:
我已将第一个列表项的图像上传到服务器(根据我的要求,我将图像状态显示为"已上传"现在已禁用上传按钮)但是当我向下/向上滚动时listview它显示列表中的任何一个项目上传而不是我上传的那个(我注意到主要是那个可见的列表项)并重置最初上传到服务器的第一个列表项的状态...
所以在这里我只想让我最初上传的那个特定的上传状态稳定...不是任何可见的项目(那些还没有上传)
只是影响列表视图,服务器上没有任何事情发生(只获取一张我上传的图片)
MainActivity.java: -
public class MainActivity extends Activity {
static ListView lstView;
private Handler handler = new Handler();;
static List <String> ImageList;
String strPath;
int position ;
static File f;
File newFile;
static File[] files ;
static File file ;
ViewHolder holder;
View v ;
String fileName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*** Get Images from SDCard ***/
ImageList = getSD();
// ListView and imageAdapter
lstView = (ListView) findViewById(R.id.listView);
lstView.setAdapter(new ImageAdapter(this));
}
private List <String> getSD()
{
List <String> it = new ArrayList <String>();
File f = new File ("/mnt/sdcard/mydata/");
File[] files = f.listFiles ();
for (int i = 0; i <files.length; i++)
{
File file = files[i];
Log.d("Count",file.getPath());
it.add (file.getPath());
}
return it;
}
static class ViewHolder {
public ViewHolder(View convertView) {
// TODO Auto-generated constructor stub
}
TextView textName;
ImageView thumbnail;
TextView textStatus;
Button btnUpload;
}
public class ImageAdapter extends BaseAdapter
{
public ImageAdapter(Context c)
{
}
public int getCount() {
// TODO Auto-generated method stub
return ImageList.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) {
// Avoid unneccessary calls to findViewById() on each row, which is expensive!
holder = null;
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.adapter_main, null);
holder = new ViewHolder(convertView);
// Create a ViewHolder and store references to the children views
holder.textName = (TextView) convertView.findViewById(R.id.textName);
holder.thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail);
holder.btnUpload = (Button) convertView.findViewById(R.id.btnUpload);
holder.textStatus = (TextView) convertView.findViewById(R.id.textStatus);
// The tag can be any Object, this just happens to be the ViewHolder
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
strPath = ImageList.get(position).toString();
// Get File Name
fileName = strPath.substring( strPath.lastIndexOf('/')+1, strPath.length() );
file = new File(strPath);
@SuppressWarnings("unused")
long length = file.length();
holder.textName.setText(fileName);
final BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(strPath,options);
holder.thumbnail.setImageBitmap(bm);
//btnUpload
holder.btnUpload.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Upload
startUpload(position);
}
});
return convertView;
}
}
// Upload
public void startUpload(final int position) {
Runnable runnable = new Runnable() {
public void run() {
handler.post(new Runnable() {
public void run() {
v = lstView.getChildAt(position - lstView.getFirstVisiblePosition());
holder = (ViewHolder) v.getTag();
holder.btnUpload.setEnabled(false);
new UploadFileAsync().execute(String.valueOf(position));
}
});
}
};
new Thread(runnable).start();
}
// Async Upload
public class UploadFileAsync extends AsyncTask<String, Void, Void> {
String resServer;
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
position = Integer.parseInt(params[0]);
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
int resCode = 0;
String resMessage = "";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
// File Path
String strSDPath = ImageList.get(position).toString();
// Upload to PHP Script
String strUrlServer = "http://10.0.2.2/uploadFile.php";
try {
/** Check file on SD Card ***/
File file = new File(strSDPath);
if(!file.exists())
{
resServer = "{\"StatusID\":\"0\",\"Message\":\"Please check path on SD Card\"}";
return null;
}
FileInputStream fileInputStream = new FileInputStream(new File(strSDPath));
URL url = new URL(strUrlServer);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream outputStream = new DataOutputStream(conn
.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream
.writeBytes("Content-Disposition: form-data; name=\"filUpload\";filename=\""
+ strSDPath + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Response Code and Message
resCode = conn.getResponseCode();
if(resCode == HttpURLConnection.HTTP_OK)
{
InputStream is = conn.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
while ((read = is.read()) != -1) {
bos.write(read);
}
byte[] result = bos.toByteArray();
bos.close();
resMessage = new String(result);
}
Log.d("resCode=",Integer.toString(resCode));
Log.d("resMessage=",resMessage.toString());
fileInputStream.close();
outputStream.flush();
outputStream.close();
resServer = resMessage.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
protected void onPostExecute(Void unused) {
statusWhenFinish(position,resServer);
}
}
// When Upload Finish
@SuppressWarnings("unused")
protected void statusWhenFinish(int position, String resServer) {
/*** Default Value ***/
String strStatusID = "0" ;
String strError = "" ;
try {
JSONObject c = new JSONObject(resServer);
strStatusID = c.getString("StatusID");
strError = c.getString("Message");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// prepare Status
if(strStatusID.equals("0"))
{
// When update Failed
holder.textStatus.setText("Failed");
holder.btnUpload.setEnabled(true);
}
else
{
holder.textStatus.setText("Uploaded");
holder.btnUpload.setEnabled(false);
}
}
}
答案 0 :(得分:1)
介绍如下结构:
/**
* Introduce a class with below attributes to hold a state of each row in single
* element
*
*/
public class MyData {
/* Image url or path of image in single row */
private String images;
/* anme of image in single row */
private String name;
/* status ID of image in single row */
private String statusID;
/* message of image in single row */
private String message;
// Generate getters and setter
public String getImages() {
return images;
}
public void setImages(String images) {
this.images = images;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStatusID() {
return statusID;
}
public void setStatusID(String statusID) {
this.statusID = statusID;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
添加了适当的注释以理解代码。
// MyDataList是arrylist ArrayList(),你需要在构造函数中初始化这个数据结构
public View getView(int position, View convertView, ViewGroup parent) {
MyData fields = MyDataList.get(position);
}
修改:
我已经编辑了上面发布的代码,请看下面的代码我如何使用MyData来设置状态
package com.example.trial;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
static ListView lstView;
private Handler handler = new Handler();;
static List<MyData> ImageList;
String strPath;
int position;
File newFile;
ViewHolder holder;
View v;
String fileName;
ImageAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*** Get Images from SDCard ***/
ImageList = getSD();
// ListView and imageAdapter
lstView = (ListView) findViewById(R.id.listView);
mAdapter = new ImageAdapter(this);
lstView.setAdapter(mAdapter);
}
private List<MyData> getSD() {
List<MyData> it = new ArrayList<MyData>();
String root_sd = Environment.getExternalStorageDirectory().toString();
File f = new File(root_sd + "/Download");
File[] files = f.listFiles();
for (int i = 0; i < files.length; i++) {
File file = files[i];
Log.d("Count", file.getPath());
MyData data = new MyData();
data.setImages(file.getPath());
data.setStatusEnable(true);
it.add(data);
}
return it;
}
static class ViewHolder {
public ViewHolder(View convertView) {
// TODO Auto-generated constructor stub
}
TextView textName;
ImageView thumbnail;
TextView textStatus;
Button btnUpload;
}
public class ImageAdapter extends BaseAdapter {
public ImageAdapter(Context c) {
}
public int getCount() {
// TODO Auto-generated method stub
return ImageList.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) {
// Avoid unneccessary calls to findViewById() on each row, which is
// expensive!
holder = null;
if (convertView == null) {
convertView = getLayoutInflater().inflate(
R.layout.adapter_main, null);
holder = new ViewHolder(convertView);
// Create a ViewHolder and store references to the children
// views
holder.textName = (TextView) convertView
.findViewById(R.id.textName);
holder.thumbnail = (ImageView) convertView
.findViewById(R.id.thumbnail);
holder.btnUpload = (Button) convertView
.findViewById(R.id.btnUpload);
holder.textStatus = (TextView) convertView
.findViewById(R.id.textStatus);
// The tag can be any Object, this just happens to be the
// ViewHolder
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.btnUpload.setEnabled(ImageList.get(position)
.isStatusEnable());
holder.textStatus.setText(ImageList.get(position).getMessage());
strPath = ImageList.get(position).getImages().toString();
// Get File Name
fileName = strPath.substring(strPath.lastIndexOf('/') + 1,
strPath.length());
File file = new File(strPath);
@SuppressWarnings("unused")
long length = file.length();
holder.textName.setText(fileName);
final BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(strPath, options);
holder.thumbnail.setImageBitmap(bm);
// btnUpload
holder.btnUpload.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Upload
startUpload(position);
}
});
return convertView;
}
}
// Upload
public void startUpload(final int position) {
Runnable runnable = new Runnable() {
public void run() {
handler.post(new Runnable() {
public void run() {
v = lstView.getChildAt(position
- lstView.getFirstVisiblePosition());
holder = (ViewHolder) v.getTag();
synchronized (this) {
ImageList.get(position).setStatusEnable(false);
mAdapter.notifyDataSetChanged();
}
new UploadFileAsync().execute(String.valueOf(position));
}
});
}
};
new Thread(runnable).start();
}
// Async Upload
public class UploadFileAsync extends AsyncTask<String, Void, Void> {
String resServer;
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
position = Integer.parseInt(params[0]);
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
int resCode = 0;
String resMessage = "";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
// File Path
String strSDPath = ImageList.get(position).getImages().toString();
// Upload to PHP Script
String strUrlServer = "http://mymasterpeice.comxa.com/uploadFile.php";
try {
/** Check file on SD Card ***/
File file = new File(strSDPath);
if (!file.exists()) {
resServer = "{\"StatusID\":\"0\",\"Message\":\"Please check path on SD Card\"}";
return null;
}
FileInputStream fileInputStream = new FileInputStream(new File(
strSDPath));
URL url = new URL(strUrlServer);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream outputStream = new DataOutputStream(
conn.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream
.writeBytes("Content-Disposition: form-data; name=\"filUpload\";filename=\""
+ strSDPath + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens
+ lineEnd);
// Response Code and Message
resCode = conn.getResponseCode();
if (resCode == HttpURLConnection.HTTP_OK) {
InputStream is = conn.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
while ((read = is.read()) != -1) {
bos.write(read);
}
byte[] result = bos.toByteArray();
bos.close();
resMessage = new String(result);
}
Log.d("resCode=", Integer.toString(resCode));
Log.d("resMessage=", resMessage.toString());
fileInputStream.close();
outputStream.flush();
outputStream.close();
resServer = resMessage.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
protected void onPostExecute(Void unused) {
statusWhenFinish(position, resServer);
}
}
// When Upload Finish
@SuppressWarnings("unused")
protected void statusWhenFinish(int position, String resServer) {
/*** Default Value ***/
String strStatusID = "0";
String strError = "";
try {
JSONObject c = new JSONObject(resServer);
strStatusID = c.getString("StatusID");
strError = c.getString("Message");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// // prepare Status
if (strStatusID.equals("0")) {
// When update Failed
ImageList.get(position).setMessage("Failed");
ImageList.get(position).setStatusEnable(true);
mAdapter.notifyDataSetChanged();
} else {
ImageList.get(position).setMessage("Uploded");
ImageList.get(position).setStatusEnable(false);
mAdapter.notifyDataSetChanged();
}
}
/**
* Introduce a class with below attributes to hold a state of each row in
* single element
*
*/
public class MyData {
/* Image url or path of image in single row */
private String images;
/* anme of image in single row */
private String name;
/* status ID of image in single row */
private String statusID;
/* message of image in single row */
private String message;
private boolean statusEnable;
public boolean isStatusEnable() {
return statusEnable;
}
public void setStatusEnable(boolean statusEnable) {
this.statusEnable = statusEnable;
}
// Generate getters and setter
public String getImages() {
return images;
}
public void setImages(String images) {
this.images = images;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStatusID() {
return statusID;
}
public void setStatusID(String statusID) {
this.statusID = statusID;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
}
答案 1 :(得分:1)
创建要使用的数据类型列表。例如。
class YourDataType{
String name, status;
Bitmap image;
}
然后使用列表来保存列表中的所有对象。
List<YourDataType> listOfObjects;
然后使用类似参数创建适配器,并将对象列表传递给适配器的构造函数。
class ImagesAdapter extends BaseAdapter{
public ImagesAdapter(Context c, List<YourDataType> listOfObjects){
this.listOfObjects = listOfObjects;
}
public View getView(params, position){
YourDataType data = listOfObjects.get(position);
//Here you can use data to access specific object and upload the specific image and then mark this object's status to marked, then you can change the status of any listview item relevant to the object.
if(data.status == uploaded)
viewHolder.textStatus.setText("Uploaded");
}
}
最佳做法是分离适配器 希望能帮助到你。如果您有任何进一步的问题,请在下面发表评论。
答案 2 :(得分:0)
你应该有一个Upload Status
数组,它将被传递给适配器,默认值为false,每次你在服务器上成功上传文件,都会将状态更改为与listitem相对应的数组。
例如
默认数组(假设列表大小为7)
{"false","false""false""false""false""false""false"}
每次成功上传文件时,请将Array的状态更改为
{"false","true""false""false""false""false""true"}
现在您只需要更新此数组中的值,并且必须调用
youradapter.notifydatasetchanged();