Using a ListView with TextViews instead of a lot of SpannableStrings in one TextView for Messages; Fixed a not closed database cursor problem

This commit is contained in:
Sebastian Kaspari 2010-03-08 21:36:36 +01:00
parent a84a8ef51c
commit add973918d
7 changed files with 268 additions and 36 deletions

View File

@ -24,15 +24,13 @@ import java.util.HashMap;
import java.util.LinkedList;
import org.yaaic.model.Channel;
import org.yaaic.model.Message;
import org.yaaic.view.MessageListView;
import android.graphics.Typeface;
import android.text.SpannableString;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.TextView;
import android.widget.ListView;
/**
* The adapter for the "DeckView"
@ -41,7 +39,7 @@ import android.widget.TextView;
*/
public class DeckAdapter extends BaseAdapter
{
private HashMap<String, View> map = new HashMap<String, View>();
private HashMap<String, MessageListView> map = new HashMap<String, MessageListView>();
private LinkedList<Channel> channels = new LinkedList<Channel>();
private View currentView;
private String currentChannel;
@ -104,7 +102,7 @@ public class DeckAdapter extends BaseAdapter
* @param channel
* @return The item
*/
public View getItemByName(String channel)
public MessageListView getItemByName(String channel)
{
if (map.containsKey(channel)) {
return map.get(channel);
@ -175,21 +173,47 @@ public class DeckAdapter extends BaseAdapter
convertView = map.get(channel.getName());
if (convertView == null) {
convertView = renderChannel(channel, parent);
map.put(channel.getName(), convertView);
MessageListView view = renderChannel(channel, parent);
map.put(channel.getName(), view);
return view;
} else {
return convertView;
}
return convertView;
}
public View renderChannel(Channel channel, ViewGroup parent)
/**
* Render a channel view (MessageListView)
*
* @param channel The channel of the view
* @param parent The parent view (context)
* @return The rendered MessageListView
*/
public MessageListView renderChannel(Channel channel, ViewGroup parent)
{
MessageListView list = new MessageListView(parent.getContext());
list.setAdapter(new MessageListAdapter(channel, parent.getContext()));
// XXX: Refactor this crap :)
float fw = (float) width;
float fh = (float) height;
float vwf = fw / 100 * 80;
float vhf = fh / 100 * 80;
int w = (int) vwf;
int h = (int) vhf;
list.setLayoutParams(new Gallery.LayoutParams(w, h));
list.setBackgroundColor(0xff222222);
list.setPadding(5, 5, 5, 5);
list.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
list.setScrollContainer(false);
return list;
/*
TextView canvas = new TextView(parent.getContext());
canvas.setBackgroundColor(0xff222222);
canvas.setPadding(5, 5, 5, 5);
canvas.setTextSize(11);
canvas.setTypeface(Typeface.MONOSPACE);
canvas.setTextColor(0xffeeeeee);
SpannableString welcome = new SpannableString("Joined " + channel.getName());
canvas.setText(welcome);
@ -213,5 +237,6 @@ public class DeckAdapter extends BaseAdapter
canvas.setLayoutParams(new Gallery.LayoutParams(w, h));
return canvas;
*/
}
}

View File

@ -0,0 +1,114 @@
/*
Yaaic - Yet Another Android IRC Client
Copyright 2009 Sebastian Kaspari
This file is part of Yaaic.
Yaaic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Yaaic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.yaaic.adapter;
import java.util.LinkedList;
import org.yaaic.model.Channel;
import org.yaaic.model.Message;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
/**
* Adapter for (channel) messages in a ListView
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class MessageListAdapter extends BaseAdapter
{
private LinkedList<TextView> messages = new LinkedList<TextView>();
private Context context;
/**
* Create a new MessageAdapter
*
* @param channel
* @param context
*/
public MessageListAdapter(Channel channel, Context context)
{
this.context = context;
for (Message message : channel.getHistory()) {
messages.add(message.renderTextView(context));
}
}
/**
* Add a message to the list
*
* @param message
*/
public void addMessage(Message message)
{
messages.add(message.renderTextView(context));
notifyDataSetChanged();
}
/**
* Get number of items
*
* @return
*/
public int getCount()
{
return messages.size();
}
/**
* Get item at given position
*
* @param position
* @return
*/
public TextView getItem(int position)
{
return messages.get(position);
}
/**
* Get id of item at given position
*
* @param position
* @return
*/
public long getItemId(int position)
{
return position;
}
/**
* Get item view for the given position
*
* @param position
* @param convertView
* @param parent
* @return
*/
public View getView(int position, View convertView, ViewGroup parent)
{
return getItem(position);
}
}

View File

@ -166,6 +166,7 @@ public class Database extends SQLiteOpenHelper
servers.put(server.getId(), server);
}
cursor.close();
return servers;
}

View File

@ -21,11 +21,13 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
package org.yaaic.model;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.widget.TextView;
/**
* A channel or server message
@ -121,4 +123,16 @@ public class Message {
return canvas;
}
public TextView renderTextView(Context context)
{
TextView canvas = new TextView(context);
canvas.setText(this.render(context));
canvas.setTextSize(11);
canvas.setTypeface(Typeface.MONOSPACE);
canvas.setTextColor(0xffeeeeee);
return canvas;
}
}

View File

@ -0,0 +1,84 @@
/*
Yaaic - Yet Another Android IRC Client
Copyright 2009 Sebastian Kaspari
This file is part of Yaaic.
Yaaic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Yaaic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.yaaic.view;
import org.yaaic.adapter.MessageListAdapter;
import android.content.Context;
import android.view.MotionEvent;
import android.widget.ListView;
/**
* A customized ListView for Messages
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class MessageListView extends ListView
{
public static final String TAG = "Yaaic/MessageListView";
private boolean delegate = true;
/**
* Create a new MessageListView
*
* @param context
*/
public MessageListView(Context context)
{
super(context);
}
/**
* Should all touch events delegated?
*
* @param delegate If true all touch events will be delegated, otherwise the listview will handle them
*/
public void setDelegateTouchEvents(boolean delegate)
{
this.delegate = delegate;
}
/**
* Handle touch screen motion events
*/
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (delegate) {
// We delegate the touch events to the underlying view
return false;
} else {
return super.onTouchEvent(event);
}
}
/**
* Get the adapter of this MessageListView
* (Helper to avoid casting)
*
* @return The MessageListAdapter
*/
public MessageListAdapter getAdapter()
{
return (MessageListAdapter) super.getAdapter();
}
}

View File

@ -49,6 +49,7 @@ import android.widget.TableLayout.LayoutParams;
import org.yaaic.R;
import org.yaaic.Yaaic;
import org.yaaic.adapter.DeckAdapter;
import org.yaaic.adapter.MessageListAdapter;
import org.yaaic.irc.IRCBinder;
import org.yaaic.irc.IRCService;
import org.yaaic.listener.ChannelListener;
@ -92,8 +93,8 @@ public class ServerActivity extends Activity implements ServiceConnection, Chann
Display d = getWindowManager().getDefaultDisplay();
deckAdapter = new DeckAdapter(d.getWidth(), d.getHeight());
deck = (Gallery) findViewById(R.id.deck);
deckAdapter = new DeckAdapter(d.getWidth(), d.getHeight());
deck.setAdapter(deckAdapter);
deck.setOnItemClickListener(this);
@ -194,22 +195,14 @@ public class ServerActivity extends Activity implements ServiceConnection, Chann
*/
public void onChannelMessage(String target)
{
Log.d(TAG, "Message for target " + target);
Message message = server.getChannel(target).pollMessage();
MessageListView view = (MessageListView) deckAdapter.getItemByName(target);
TextView canvas = (TextView) deckAdapter.getItemByName(target);
if (canvas != null) {
canvas.append(message.render(canvas.getContext()));
int y = (canvas.getLineCount() * canvas.getLineHeight()) - canvas.getHeight() + 20;
//Log.d(TAG, "Scrolling to: " + y);
canvas.scrollTo(0, y);
deckAdapter.notifyDataSetChanged();
if (target.equals(deckAdapter.getSwitchedName())) {
((TextView) deckAdapter.getSwitchedView()).append(message.render(canvas.getContext()));
}
} else {
Log.d(TAG, "No canvas found");
if (view != null) {
MessageListAdapter adapter = view.getAdapter();
adapter.addMessage(message);
}
}
@ -231,11 +224,11 @@ public class ServerActivity extends Activity implements ServiceConnection, Chann
Log.d(TAG, "Selected channel: " + position);
Channel channel = deckAdapter.getItem(position);
view = deckAdapter.renderChannel(channel, switcher);
//getView(position, view, deck);
view.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
deckAdapter.setSwitched(channel.getName(), view);
switcher.addView(view);
MessageListView canvas = deckAdapter.renderChannel(channel, switcher);
canvas.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
canvas.setDelegateTouchEvents(false); // Do not delegate
deckAdapter.setSwitched(channel.getName(), canvas);
switcher.addView(canvas);
switcher.showNext();
}

View File

@ -216,6 +216,7 @@ public class ServersActivity extends ListActivity implements ServiceConnection,
{
Database db = new Database(this);
db.removeServerById(serverId);
db.close();
Yaaic.getInstance().removeServerById(serverId);
adapter.loadServers();