我的自定义列表视图无法正常工作。它工作正常,直到我没有滚动到最后,但当我滚动结束其onclick功能停止工作,我使用自定义列表扩展基础适配器..
我已将点击侦听器设置为toogle,为此,我已在自定义行中将focusable设置为false。
但我注意到的一点是,只要我的列表停止点击,就会在日志中生成以下错误。
05-18 17:54:02.674: W/KeyCharacterMap(4343): Can't open keycharmap file
05-18 17:54:02.674: W/KeyCharacterMap(4343): Error loading keycharmap file '/system/usr/keychars/cy8c-touchscreen.kcm.bin'. hw.keyboards.65537.devname='cy8c-touchscreen'
05-18 17:54:02.674: I/KeyCharacterMap(4343): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
列表视图
<ListView
android:id="@+id/main_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="3dp"
android:cacheColorHint="#00000000"
android:clickable="true"
android:divider="@null"
android:dividerHeight="0dp"
android:listSelector="@android:color/transparent"
android:smoothScrollbar="true" >
</ListView>
自定义行
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="@drawable/main_row" >
<ToggleButton
android:id="@+id/row_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/row_fri"
android:layout_alignLeft="@+id/row_fri"
android:background="@drawable/tog_selector"
android:focusable="false"
android:text="ToggleButton"
android:textOff=""
android:textOn="" />
</RelativeLayout>
主类
package com.personoids.personoid;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.text.format.Formatter;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
@SuppressLint("NewApi")
public class Main extends Activity implements OnClickListener, OnItemClickListener, OnItemLongClickListener{
Intent add_alarm;
ListView main_list;
StateListDrawable state_list;
Db_alarm db;
Alarm_info[] data;
CategoryAdapter main_adapter;
TextView next_date;
TextView next_time;
TextView next_in;
int cur_position;
float text_size;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
TextView custom_title = (TextView) findViewById(R.id.custom_title);
custom_title.setText("Alarm Clock Wise");
init_vars();
clock_update();
populatelist();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if((v.getId() == R.id.add_alarm_text) ||( v.getId() == R.id.add_alarm_icon))
{
add_alarm = new Intent(this, Add_Alarm.class);
add_alarm.putExtra("edit", 0);
startActivity(add_alarm);
}
}
public void clock_update()
{
long time_millis = System.currentTimeMillis();
long hr;
long min;
String am_pm = "AM";
String time = null;
TimeZone timeZone = TimeZone.getDefault();
int gmt = timeZone.getRawOffset()/(60 * 60 * 1000);
hr = (time_millis/(1000*60*60)%24)+gmt;
min = (time_millis/(1000*60)%60);
if (hr >= 12 && hr <24)
{
am_pm = "PM";
}
hr= hr%12;
if(hr == 0)
hr = 12;
TextView clock = (TextView) findViewById(R.id.alarm_clock);
clock.setText(String.format("%02d:%02d "+ am_pm, hr,min));
Timer clock_timer = new Timer();
int delay =(60 - ((int)((time_millis/1000)%60))) * 1000;
int period = 60000;
clock_timer.scheduleAtFixedRate(new TimerTask()
{
long hr;
long min;
long time_millis;
String am_pm = "AM";
String time = null;
TextView clock = (TextView) findViewById(R.id.alarm_clock);
TimeZone timeZone = TimeZone.getDefault();
int gmt = timeZone.getRawOffset()/(60 * 60 * 1000);
@Override
public void run() {
// TODO Auto-generated method stub
time_millis = System.currentTimeMillis();
hr = (time_millis/(1000*60*60)%24)+gmt;
min = (time_millis/(1000*60)%60);
if (hr >= 12 && hr <24)
{
am_pm = "PM";
}
hr= hr%12;
if(hr == 0)
hr = 12;
clock.post(new Runnable()
{
public void run()
{
runOnUiThread(new Runnable()
{
public void run()
{
clock.setText(String.format("%02d:%02d "+ am_pm, hr,min));
populatelist();
}
});
}
});
}
}, delay,period);
}
public void init_vars()
{
RelativeLayout row1= (RelativeLayout) findViewById(R.id.row1);
Drawable row = row1.getBackground();
next_date = (TextView) findViewById(R.id.next_alarm_date);
next_time = (TextView) findViewById(R.id.next_alarm_time);
next_in = (TextView) findViewById(R.id.next_alarm_time_left);
//list_row.getAlpha();
//row1.setAlpha(80);
row.setAlpha(80);
row1.setBackgroundDrawable(row);
TextView clock = (TextView) findViewById(R.id.alarm_clock);
TextView next_time = (TextView) findViewById(R.id.next_alarm_time);
Typeface ethnocen = Typeface.createFromAsset(getAssets(), "fonts/ethnocen.ttf");
Typeface goodtime = Typeface.createFromAsset(getAssets(), "fonts/goodtime.ttf");
TextView add_alarm_text = (TextView) findViewById(R.id.add_alarm_text);
ImageView add_alarm_icon = (ImageView) findViewById(R.id.add_alarm_icon);
clock.setTypeface(ethnocen);
next_time.setTypeface(goodtime);
add_alarm_text.setOnClickListener(this);
add_alarm_icon.setOnClickListener(this);
db = new Db_alarm(this);
data = db.ret_alarm_info();
main_adapter = new CategoryAdapter(Main.this, data);
main_list = (ListView) findViewById(R.id.main_list);
main_list.setAdapter(main_adapter);
main_list.setOnItemClickListener(this);
main_list.setOnItemLongClickListener(this);
registerForContextMenu(main_list);
text_size = next_time.getTextSize();
main_list.post(new Runnable() {
public void run() {
main_adapter.notifyDataSetChanged();
}
});
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater men_inflater = getMenuInflater();
men_inflater.inflate(R.menu.context_rows, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId())
{
case R.id.delete:
db.delete(data[cur_position].getid());
cancel_pendings(data[cur_position].getid());
break;
case R.id.edit:
add_alarm = new Intent(this, Add_Alarm.class);
add_alarm.putExtra("alarm_info", data[cur_position]);
add_alarm.putExtra("links", db.ret_links(data[cur_position].getid()));
add_alarm.putExtra("edit", 1);
startActivity(add_alarm);
break;
case R.id.duplicate:
db.duplicate(data[cur_position].getid());
int id = db.return_last_id();
Intent i = new Intent(this, launch_alarm.class);
i.putExtra("id", id);
PendingIntent pi = PendingIntent.getActivity(this, id, i, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
data[cur_position] = db.ret_alarm_row(id);
int secs = calendar.get(Calendar.SECOND);
secs = 60-secs;
calendar.setTimeInMillis(System.currentTimeMillis());
int day = data[cur_position].days_left()*24;
int hr = data[cur_position].hours_left()+day;
hr = hr*60;
int min = data[cur_position].mins_left()+hr;
min--;
calendar.add(Calendar.MINUTE, min);
calendar.add(Calendar.SECOND, secs);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
break;
case R.id.clear:
for(int j = 0; j < data.length ; j++)
{
db.delete(data[j].getid());
cancel_pendings(data[j].getid());
}
break;
}
//Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
populatelist();
return super.onContextItemSelected(item);
}
@Override
public void onItemClick(AdapterView<?> arg0, View v, int pos, long arg3) {
// TODO Auto-generated method stub
}
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int pos,
long arg3) {
// TODO Auto-generated method stub
cur_position = pos;
return false;
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
populatelist();
}
private void populatelist() {
// TODO Auto-generated method stub
data = db.ret_alarm_info();
main_adapter.update(data);
update_next();
}
public void update_next()
{
ArrayList<Integer> min = new ArrayList<Integer>();
int minimum =0;
int index=0;
int found =0;
int counter = 0;
String[] months = {"January","February","March","April","May","June","July","August","September","October","November","December"};
String[] days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
while(found==0 && counter < data.length)
{
if(data[counter].activated()==1)
{
minimum=(data[counter].days_left()*24*60)+(data[counter].hours_left()*60)+(data[counter].mins_left());
min.add(counter);
found=1;
}
counter++;
}
Log.i("1", "1");
if(counter <= data.length)
{Log.i("2", "1");
for(int i = counter; i < data.length ; i++)
{
if((((data[i].days_left()*24*60)+(data[i].hours_left()*60)+(data[i].mins_left()))<minimum&&
data[i].activated()==1))
{
minimum=(data[i].days_left()*24*60)+(data[i].hours_left()*60)+(data[i].mins_left());
min.add(i);
}
}
for(int i = 0; i < min.size();i++)
index = min.get(min.size()-1);
}
if(data.length == 0 || found==0)
{
Log.i("3", "1");
next_date.setText("");
next_in.setText("");
next_time.setText("No Alarm");
int sizes =(int)((22*getResources().getDisplayMetrics().density)+0.5);
next_time.setTextSize((float)sizes);
}
else
{
Log.i("4", "1");
next_time.setTextSize(text_size);
Calendar cal= Calendar.getInstance();
cal.add(Calendar.DAY_OF_WEEK, data[index].days_left());
cal.add(Calendar.HOUR_OF_DAY, data[index].hours_left());
cal.add(Calendar.MINUTE, data[index].mins_left());
//
String next_day = days[cal.get(Calendar.DAY_OF_WEEK)-1];
String next_month = months[cal.get(Calendar.MONTH)];
String date = cal.get(Calendar.DAY_OF_MONTH)+"";
if(date.equals("1") || date.equals("21"))
date = date+"st";
else if(date.equals("2") || date.equals("22"))
date = date+"nd";
else if(date.equals("3") || date.equals("23"))
date = date+"rd";
else
date = date+"th";
next_date.setText(next_day+" "+date+" "+next_month);
int time_hrs = data[index].time_hrs();
String am_pm = "AM";
if(time_hrs>11)
{
if(time_hrs>12)
time_hrs = time_hrs % 12;
am_pm = "PM";
}
if(time_hrs == 0)
{
time_hrs= 12;
}
next_time.setText(String.format("%02d:%02d "+am_pm, time_hrs,data[index].time_mins()));
next_in.setText(String.format("In %d hrs %d mins", data[index].days_left()*24+data[index].hours_left(), data[index].mins_left()));
}
}
public void cancel_pendings(int id)
{
Intent i = new Intent(this, launch_alarm.class);
PendingIntent pi = PendingIntent.getActivity(this, id, i, PendingIntent.FLAG_UPDATE_CURRENT);
pi.cancel();
}
public void set_alarm(int id, int day, int hr, int min)
{
Intent i = new Intent(this, launch_alarm.class);
i.putExtra("id", id);
PendingIntent pi = PendingIntent.getActivity(this, id, i, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
int secs = calendar.get(Calendar.SECOND);
secs = 60-secs;
calendar.setTimeInMillis(System.currentTimeMillis());
day = day*24;
hr = hr+day;
hr = hr*60;
min = min+hr;
min--;
calendar.add(Calendar.MINUTE, min);
calendar.add(Calendar.SECOND, secs);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(Menu.NONE, 0, 0, "Add Alarm").setIcon(R.drawable.add);
menu.add(Menu.NONE, 1, 1, "Clear list").setIcon(R.drawable.clear);
menu.add(Menu.NONE, 2, 2, "Rate").setIcon(R.drawable.rate);
menu.add(Menu.NONE, 3, 3, "Upgrade").setIcon(R.drawable.upgrade);
menu.add(Menu.NONE, 4, 4, "Help").setIcon(R.drawable.help);
menu.add(Menu.NONE, 5, 5, "Close").setIcon(R.drawable.close);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case 0:
add_alarm = new Intent(this, Add_Alarm.class);
add_alarm.putExtra("edit", 0);
startActivity(add_alarm);
break;
case 1:
for(int j = 0; j < data.length ; j++)
{
db.delete(data[j].getid());
cancel_pendings(data[j].getid());
}
populatelist();
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
}
自定义适配器
package com.personoids.personoid;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.webkit.WebView.FindListener;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
@SuppressLint("NewApi")
public class CategoryAdapter extends BaseAdapter implements OnClickListener {
private Main catActivity;
private Alarm_info[] data;
private Context co;
RelativeLayout rl ;
Drawable d;
Db_alarm db;
TextView alarm_time;
TextView remaining;
TextView sun;
TextView mon;
TextView tue;
TextView wed;
TextView thu;
TextView fri;
TextView sat;
ToggleButton toggle;
public CategoryAdapter(Context c, Alarm_info[] datas) {
co = c;
data = datas;
}
@SuppressWarnings("deprecation")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final int pos = position;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) co.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v= inflater.inflate(R.layout.main_row, null);
}
// v.setOnClickListener(this);
//v.setOnFocusChangeListener(this);
rl = (RelativeLayout) v.findViewById(R.id.list_row);
d =rl.getBackground();
d.setAlpha(80);
rl.setBackgroundDrawable(d);
int[] days = data[position].days();
alarm_time = (TextView) v.findViewById(R.id.row_alarm_time);
int time_hrs = data[position].time_hrs();
String am_pm = "AM";
if(time_hrs>11)
{
if(time_hrs>12)
time_hrs = time_hrs % 12;
am_pm = "PM";
}
if(time_hrs == 0)
{
time_hrs= 12;
}
alarm_time.setText(String.format("%02d:%02d "+am_pm, time_hrs,data[position].time_mins()));
alarm_time.setTag(position);
remaining = (TextView) v.findViewById(R.id.row_rem_time);
remaining.setTag(position);
remaining.setText(String.format("%dd %dh %dm", data[position].days_left(),data[position].hours_left(),data[position].mins_left()));
TextView description = (TextView) v.findViewById(R.id.row_desc);
description.setTag(position);
description.setText(data[position].getdesc());
sun = (TextView) v.findViewById(R.id.row_sun);
sun.setTag(position);
if(days[0]==0)
sun.setTextColor(Color.parseColor("#50ffffff"));
else
sun.setTextColor(Color.parseColor("#ffffffff"));
mon = (TextView) v.findViewById(R.id.row_mon);
mon.setTag(position);
if(days[1]==0)
mon.setTextColor(Color.parseColor("#50ffffff"));
else
mon.setTextColor(Color.parseColor("#ffffffff"));
tue = (TextView) v.findViewById(R.id.row_tue);
tue.setTag(position);
if(days[2]==0)
tue.setTextColor(Color.parseColor("#50ffffff"));
else
tue.setTextColor(Color.parseColor("#ffffffff"));
wed = (TextView) v.findViewById(R.id.row_wed);
wed.setTag(position);
if(days[3]==0)
wed.setTextColor(Color.parseColor("#50ffffff"));
else
wed.setTextColor(Color.parseColor("#ffffffff"));
thu = (TextView) v.findViewById(R.id.row_thu);
thu.setTag(position);
if(days[4]==0)
thu.setTextColor(Color.parseColor("#50ffffff"));
else
thu.setTextColor(Color.parseColor("#ffffffff"));
fri = (TextView) v.findViewById(R.id.row_fri);
fri.setTag(position);
if(days[5]==0)
fri.setTextColor(Color.parseColor("#50ffffff"));
else
fri.setTextColor(Color.parseColor("#ffffffff"));
sat = (TextView) v.findViewById(R.id.row_sat);
sat.setTag(position);
if(days[6]==0)
sat.setTextColor(Color.parseColor("#50ffffff"));
else
sat.setTextColor(Color.parseColor("#ffffffff"));
if(data[position].activated()==0)
{
remaining.setText("Disabled");
notifyDataSetChanged();
}
if(data[position].skip==1 && data[position].activated()==1)
{
remaining.setText("Snoozed: "+data[position].snooze_duration+" min");
notifyDataSetChanged();
}
toggle = (ToggleButton) v.findViewById(R.id.row_toggle);
toggle.setTag(position);
if(data[position].activated()==0)
toggle.setChecked(false);
else
toggle.setChecked(true);
toggle.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
db = new Db_alarm(co);
if(data[pos].activated==0)
{
db.activate(data[pos].getid());
data[pos].activated=1;
((Main) co).set_alarm(data[pos].getid(), data[pos].days_left(), data[pos].hours_left(), data[pos].mins_left());
}
else
{
db.deactivate(data[pos].getid());
db.iskip(data[pos].getid(), 0);
data[pos].activated=0;
data[pos].skip=0;
((Main) co).cancel_pendings(data[pos].getid());
}
((Main) co).update_next();
notifyDataSetChanged();
}
});
return v;
}
public void update(Alarm_info[] datas)
{
data=datas;
notifyDataSetChanged();
}
@Override
public void onClick(View view) {
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}