【发布时间】:2015-09-28 06:55:36
【问题描述】:
所以,我已经搜索了互联网,但我无法根据其他人的经验找到解决方案,所以我发布了这个问题。 (请注意,这是我的第一次 Android 应用体验,我正在调试/更新现有应用。)
当我在 ListView、mListNotesView (mListNotesView.setAdapter(this)) 上实现我的自定义 NotesListAdapter(扩展 BaseAdapter)并将数据加载到 ArrayList mNoteList 中时,不会调用 getView 函数。另外,我发现 mListNotesView.setBackgroundResource 也没有改变控件的背景。我对以前的活动有一个类似的实现,它完全正确。当我复制该类并将其更改为处理我的 ArrayList 时,它坏了。我有 getCount 返回 ArrayList size(),它不是 0,而 getItemId 返回位置。我有一种感觉,它可能是我的 XML 或我的设置,因为它的行为就像 ListView 不可见一样。我很困惑。如何让 ListView 显示?尚未到达 getView 内部的任何内容,因此可能存在错误。
ViewTicketOrderActivity(部分尺寸省略)
public class ViewTicketOrderActivity extends Activity {
MySQLDatabase myDataBase;
Ticket mTicket;
public ArrayList<Notes> mNotes = new ArrayList<Notes>();
String mErrorString;
Button mAddUpdateButton;
Button mAcceptButton;
//Button mViewNotesButton;
NotesListAdapter mNotesListAdapter;
static final int ERROR_DIALOG = 0;
static final int SUCCESS_DIALOG = 1;
static final int COMPLETED_DIALOG = 2;
static final int RESTART_DIALOG = 3;
static final int LOADING = 0;
static final int LOAD_ERROR = 1;
static final int LOADED = 4;
static final String TICKET_EXTRA = "ticket_extra";
static final String TAG = "ViewTicketOrderActivity";
private static final boolean gDebugLog = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewticketorder);
Activity context = this;
String theTitle = "Sundance Ticket Order";
theTitle += (MySQLDatabase.TESTING == true) ? " (DEV SERVER)" : " (LIVE)";
setTitle(theTitle);
myDataBase = MySQLDatabase.getMySQLDatabase(this);
if (gDebugLog) {
DebugLogger.logString(TAG, ".onCreate");
}
mNotesListAdapter = new NotesListAdapter(context, R.id.note_list);
Log.d(this.toString(),this.mNotesListAdapter.toString());
}
private class NotesListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<Notes> mNoteList;
private ListView mListNotesView;
private Activity mActivity;
int mState = LOADING;
String mErrorMessage;
private NotesListAdapter(Activity context, int listViewID) {
mActivity = context;
mNoteList = new ArrayList<Notes>();
mInflater = LayoutInflater.from(context);
mListNotesView = (ListView)context.findViewById(listViewID);
mListNotesView.setBackgroundResource(R.color.emergency_red);
mListNotesView.setAdapter(this);
Log.d(mListNotesView.toString(), String.valueOf(mListNotesView.getCount()));
this.notifyDataSetChanged();
//mListNotesView.setVisibility(View.VISIBLE);
}
void setLoading()
{
mState = LOADING;
this.notifyDataSetChanged();
}
void setLoadError(String errorString)
{
mState = LOAD_ERROR;
mErrorMessage = errorString;
this.notifyDataSetChanged();
}
void setNoteList(ArrayList<Notes> inNotes)
{
mState = LOADED;
mNoteList.clear();
mNoteList.addAll(inNotes);
Log.d("SetNoteList", "TRUE " + inNotes);
//mNoteList = mNotes;
this.notifyDataSetChanged();
}
/**
* Use the array index as a unique id.
*
* @see android.widget.ListAdapter#getItemId(int)
*/
@Override
public long getItemId(int position) {
return position;
}
public int getCount(){
if (mState == LOADED) {
Log.d("getCount",String.valueOf(mNoteList.size()));
return mNoteList.size();
} else {
return 0;
}
}
/**
* Make a view to hold each row.
*
* @see android.widget.ListAdapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
Log.d("getView",this.toString());
if (mState == LOADED) {
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there
// is no need
// to reinflate it. We only inflate a new View when the
// convertView supplied
// by ListView is null.
Notes note = this.getItem(position);
if (convertView == null) {
/*if (ticket.emergency())
{
convertView = mInflater.inflate(R.layout.emergency_ticket_list_item_opt,
null);
}
else
{
convertView = mInflater.inflate(R.layout.ticket_list_item,
null);
}*/
convertView = mInflater.inflate(R.layout.noteslist_item,
null);
// Creates a ViewHolder and store references to the two
// children views
// we want to bind data to.
holder = new ViewHolder();
holder.noteText = (TextView) convertView
.findViewById(R.id.text_note);
holder.dateText = (TextView) convertView
.findViewById(R.id.text_note_date);
holder.createByText = (TextView) convertView
.findViewById(R.id.text_note_by);
holder.createByIDText = (TextView) convertView
.findViewById(R.id.text_note_by_id);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the
// TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.noteText.setText(note.note());
holder.dateText.setText(note.date());
holder.createByText.setText(note.createBy());
holder.createByIDText.setText(note.employeeID());
if(!mTicket.employeeID().equals(note.employeeID())){
convertView.setBackgroundResource(R.drawable.solid_purple);
}
} else if (mState == LOADING ) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.loading_view,
null);
}
TextView messageText = (TextView)convertView.findViewById(R.id.message);
messageText.setText("Loading tickets");
} else if (mState == LOAD_ERROR) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.load_error_view,
null);
}
TextView messageText = (TextView)convertView.findViewById(R.id.message);
messageText.setText("Error loading tickets");
String errorString = mErrorMessage != null ? mErrorMessage : "";
TextView errorText = (TextView)convertView.findViewById(R.id.errorText);
errorText.setText(errorString);
}
return convertView;
}
class ViewHolder {
TextView noteText;
TextView dateText;
TextView createByText;
TextView createByIDText;
}
//@Override
/*public int getCount() {
*//*if (mState == LOADED) {
*//*
Log.d("getCount mState " + mState,String.valueOf(mNoteList.size())+", "+String.valueOf(mNotes.size()));
return mNoteList.size();
*//*} else {
Log.d("getCount mState " + mState,"0");
return 0;
}*//*
}*/
@Override
public Notes getItem(int position) {
Log.d("getItem",mNoteList.get(position).toString());
return mNoteList.get(position);
}
@Override
public int getItemViewType (int position) {
int result = mState;
Log.d("getItemId",String.valueOf(position));
return result;
}
@Override
public int getViewTypeCount ()
{
return 4;
}
}
protected void onResume() {
super.onResume();
Bundle extras = getIntent().getExtras();
if(extras !=null)
{
mTicket = (Ticket)extras.getSerializable(TICKET_EXTRA);
}
else
{
mTicket = new Ticket();
}
if (mTicket.emergency())
{
setContentView(R.layout.view_emergency_ticketorder);
}
else
{
setContentView(R.layout.viewticketorder);
}
if (gDebugLog)
{
DebugLogger.logString(TAG, ".onResume mTicket " + mTicket);
}
TicketCheckService.clearNotificationForNewTicket(mTicket);
new GetTicketTask().execute();
new GetNotesTask().execute();
updateDisplayedTicket();
}
private void updateDisplayedTicket() {
mAddUpdateButton = (Button)findViewById(R.id.addUpdateButton);
mAcceptButton = (Button)findViewById(R.id.acceptButton);
//mViewNotesButton = (Button)findViewById(R.id.viewNotesButton);
String ticketStatus = myDataBase.getDescriptionStringForStatusString(mTicket.status());
if(ticketStatus == "Job Rejected") {
mAddUpdateButton.setText("Restart Job");
} else {
mAddUpdateButton.setText("Add Update");
}
if(ticketStatus == "Requested") {
mAcceptButton.setText("Accept");
} else if(ticketStatus != "Requested") {
mAcceptButton.setText("Back");
}
//mViewNotesButton.setText(R.string.viewNotes);
TextView idText = (TextView)findViewById(R.id.textTicketID);
idText.setText(mTicket.id());
//TextView descriptionText = (TextView)findViewById(R.id.textDescription);
//descriptionText.setText(mTicket.description());
TextView titleText = (TextView)findViewById(R.id.textTitle);
titleText.setText(mTicket.title());
TextView storeIDText = (TextView)findViewById(R.id.textStoreID);
storeIDText.setText(mTicket.store());
String formatPhone;
TextView storePhoneText = (TextView)findViewById(R.id.textStorePhone);
if(mTicket.phoneNo().isEmpty()){
formatPhone = "NO PHONE NO.";
} else {
storePhoneText = (TextView) findViewById(R.id.textStorePhone);
formatPhone = mTicket.phoneNo().replaceFirst("(\\d{3})(\\d{3})(\\d+)", "($1)$2-$3");
storePhoneText.setOnClickListener(new CallClickListener(mTicket.phoneNo()));
}
storePhoneText.setText(formatPhone);
TextView categoryText = (TextView)findViewById(R.id.textCategory);
String categoryDescription = MySQLDatabase.getDescriptionStringForCategoryString(mTicket.category());
categoryText.setText(categoryDescription);
if(ticketStatus == "Completed Pending") {
showDialog(COMPLETED_DIALOG);
}
}
public void onClickAccept(View v) {
try {
boolean maint = myDataBase.getSystemMaintStatus();
if(maint) {
setLoadError("The phone app is down for maintenance.");
return;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mAcceptButton.getText() =="Accept") {
mAddUpdateButton.setEnabled(false);
mAcceptButton.setEnabled(false);
new AcceptTicketTask().execute();
} else {
finish();
}
}
public void onClickAddUpdate(View v) {
try {
boolean maint = myDataBase.getSystemMaintStatus();
if(maint) {
setLoadError("The phone app is down for maintenance.");
return;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mAddUpdateButton.getText() =="Add Update") {
Intent i = new Intent(this, UpdateTicketActivity.class);
i.putExtra(UpdateTicketActivity.TICKET_EXTRA, mTicket);
startActivity(i);
} else if(mAddUpdateButton.getText() =="Restart Job") {
mAddUpdateButton.setEnabled(false);
mAcceptButton.setEnabled(false);
new RestartTicketTask().execute();
}
}
private class AcceptTicketTask extends AsyncTask<Void, Integer, String>
{
protected String doInBackground(Void... parent) {
mErrorString = null;
String result = null;
String updateTime = DateFormat.getDateTimeInstance().format(new Date(0));
try {
boolean success = myDataBase.updateTicket(mTicket.id(), mTicket.employeeID(), mTicket.description(), "1", updateTime, null);
if (!success)
{
result = "Could not update Ticket";
}
} catch (IOException e) {
// TODO Auto-generated catch block
result = "Could not update Ticket - " + e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(String errorString) {
if (null != errorString) {
mErrorString = errorString;
showDialog(ERROR_DIALOG);
} else {
showDialog(SUCCESS_DIALOG);
mAcceptButton.setText("Back");
}
mAddUpdateButton.setEnabled(true);
mAcceptButton.setEnabled(true);
}
}
private class RestartTicketTask extends AsyncTask<Void, Integer, String>
{
protected String doInBackground(Void... parent) {
mErrorString = null;
String result = null;
String updateTime = DateFormat.getDateTimeInstance().format(new Date(0));
try {
boolean success = myDataBase.updateTicket(mTicket.id(), mTicket.employeeID(), mTicket.description(), "7", updateTime, null);
if (!success)
{
result = "Could not update Ticket";
}
} catch (IOException e) {
// TODO Auto-generated catch block
result = "Could not update Ticket - " + e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(String errorString)
{
if (null != errorString) {
mErrorString = errorString;
showDialog(ERROR_DIALOG);
} else {
showDialog(RESTART_DIALOG);
mAcceptButton.setText("Done");
mAddUpdateButton.setText("Add Update");
}
mAddUpdateButton.setEnabled(true);
mAcceptButton.setEnabled(true);
}
}
private class GetTicketTask extends AsyncTask<Void, Integer, Ticket>
{
String mError = null;
protected Ticket doInBackground(Void... parent) {
Ticket result = null;
try {
result = myDataBase.getTicketWithID(mTicket.id(), mTicket.employeeID());
} catch (IOException e) {
// TODO Auto-generated catch block
mError = e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(Ticket result)
{
if (null != result) {
mTicket = result;
} else {
setLoadError(mError);
}
}
}
private class GetNotesTask extends AsyncTask<Void, Integer, ArrayList<Notes>> {
String mError = null;
protected ArrayList<Notes> doInBackground(Void... parent) {
ArrayList<Notes> result = new ArrayList<Notes>();
try {
result = myDataBase.getTicketNotes(mTicket.id());
} catch (IOException e) {
// TODO Auto-generated catch block
myDataBase.debugLog("Error caught" + e);
mError = e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(ArrayList<Notes> result) {
if (null != result) {
Log.d("Result", result.toString());
mNotes = result;
} else {
Log.d("SetNoteList","FALSE");
mNotesListAdapter.setLoadError(mError);
}
}
}
private void updateDisplayedNotes(){
ArrayList<Notes> newNotes = mNotes;
if(newNotes != null) {
mNotesListAdapter.setNoteList(newNotes);
}
}
/*private class updateDisplayedNotes extends AsyncTask<Void, Integer, ArrayList<Notes>> {
public ArrayList<Notes> newNotes = new ArrayList<Notes>();
public updateDisplayedNotes(){
super();
Log.d(this.toString(), "Updating");
}
protected ArrayList<Notes> doInBackground(Void... parent) {
Log.d(this.toString(), "Background Task");
for (Notes note : mNotes) {
Log.d(this.toString(),note.toString());
if(note != null) {
Log.d(this.toString(), "Note Added");
newNotes.add(note);
}
}
return newNotes;
}
protected void onPostExecute(ArrayList<Notes> newNotes)
{
if(newNotes != null) {
mNotes.clear();
mNotes.addAll(newNotes);
mNotesListAdapter.setNoteList(mNotes);
}
}
}*/
void setLoadError(String error) {
setContentView(R.layout.load_error_view);
TextView messageText = (TextView)findViewById(R.id.message);
messageText.setText("Error loading ticket");
String errorString = error != null ? error : "";
TextView errorText = (TextView)findViewById(R.id.errorText);
errorText.setText(errorString);
finish();
}
}
viewticketorder.xml(note_list 所在的位置)
<?xml version="1.0" encoding="utf-8"?>
<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:background="@drawable/background"
android:orientation="vertical"
tools:context=".ViewTicketOrderActivity"
tools:ignore="HardcodedText" >
<TextView
android:id="@+id/textTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:text="@string/loadingTicket"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/white_color"
android:textSize="20dp"
android:textIsSelectable="true"
android:background="@drawable/title_transparent_bg"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:paddingTop="2dp"
android:paddingLeft="10dp"
android:text="@string/ticketID"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/textTicketID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:focusable="true"
android:textColor="@color/white_color"
android:textIsSelectable="true"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:paddingTop="2dp"
android:text="@string/storeID"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/textStoreID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:focusable="true"
android:textColor="@color/white_color"
android:textIsSelectable="true"/>
<TextView
android:id="@+id/textStorePhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:focusable="true"
android:textColor="@color/white_color"
android:textIsSelectable="true"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/TextView05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:paddingTop="2dp"
android:text="@string/category"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/textCategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center_vertical"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/white_color"
android:focusable="true"
android:textIsSelectable="true"/>
</LinearLayout>
<ListView
android:id="@+id/note_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:divider="@drawable/ticket_item_divider"
android:dividerHeight="1dp"
tools:ignore="NestedWeights"
android:choiceMode="singleChoice"
android:clickable="true"
android:background="@drawable/title_transparent_bg">
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/acceptButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="2dp"
android:layout_weight="1"
android:onClick="onClickAccept" />
<Button
android:id="@+id/addUpdateButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:onClick="onClickAddUpdate" />
</LinearLayout>
</LinearLayout>
notelist_item.xml(充气机)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text_note_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#80FFFFFF"
android:orientation="vertical"
>
<TextView
android:id="@+id/text_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/filler_string"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/text_item_color"
android:textSize="@dimen/big_text_item_size" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight=".70"
>
<TextView
android:id="@+id/text_note_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/filler_string"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/text_sub_item_color" />
<TextView
android:id="@+id/text_note_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/filler_string"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/text_sub_item_color" />
<TextView
android:id="@+id/text_note_by_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/filler_string"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/text_sub_item_color" />
</LinearLayout>
</LinearLayout>
【问题讨论】:
-
您创建了适配器,但从未将其分配给 ListView。
-
谢谢!我只是在 UpdateDisplayedTicket() 函数中分配了它。
标签: java android listview arraylist baseadapter