Replace gallery view for conversations by ViewPager. Fixes #38.

This commit is contained in:
Sebastian Kaspari 2012-01-21 08:56:40 +01:00
parent 659d6c0b89
commit e04499070a
8 changed files with 226 additions and 490 deletions

View File

@ -38,7 +38,7 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
android:src="@drawable/disconnected"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="3dp"
android:textSize="12sp"
@ -46,20 +46,15 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
android:maxLines="1"
android:layout_weight="1" />
</LinearLayout>
<ViewSwitcher
android:id="@+id/switcher"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<org.yaaic.view.ConversationGallery
android:id="@+id/deck"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="0px"
android:unselectedAlpha="100"
android:spacing="5dp"
android:padding="0dp" />
</ViewSwitcher>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="0px"
android:unselectedAlpha="100"
android:spacing="5dp"
android:padding="0dp" />
<org.yaaic.view.ConversationSwitcher
android:id="@+id/dots"
android:layout_width="wrap_content"
@ -70,7 +65,7 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
android:orientation="horizontal">
<EditText
android:id="@+id/input"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textImeMultiLine"

View File

@ -26,14 +26,13 @@ import java.util.List;
import org.yaaic.R;
import org.yaaic.Yaaic;
import org.yaaic.adapter.DeckAdapter;
import org.yaaic.adapter.ConversationPagerAdapter;
import org.yaaic.adapter.MessageListAdapter;
import org.yaaic.command.CommandParser;
import org.yaaic.irc.IRCBinder;
import org.yaaic.irc.IRCConnection;
import org.yaaic.irc.IRCService;
import org.yaaic.layout.NonScalingBackgroundDrawable;
import org.yaaic.listener.ConversationClickListener;
import org.yaaic.listener.ConversationListener;
import org.yaaic.listener.ConversationSelectedListener;
import org.yaaic.listener.ServerListener;
@ -53,7 +52,6 @@ import org.yaaic.model.User;
import org.yaaic.receiver.ConversationReceiver;
import org.yaaic.receiver.ServerReceiver;
import org.yaaic.view.ConversationSwitcher;
import org.yaaic.view.MessageListView;
import android.app.Activity;
import android.app.AlertDialog;
@ -69,28 +67,27 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.speech.RecognizerIntent;
import android.support.v4.view.ViewPager;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnKeyListener;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
/**
* The server view with a scrollable list of all channels
*
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class ConversationActivity extends Activity implements ServiceConnection, ServerListener, ConversationListener
@ -108,9 +105,9 @@ public class ConversationActivity extends Activity implements ServiceConnection,
private ConversationReceiver channelReceiver;
private ServerReceiver serverReceiver;
private ViewSwitcher switcher;
private Gallery deck;
private DeckAdapter deckAdapter;
private ViewPager pager;
private ConversationPagerAdapter pagerAdapter;
private Scrollback scrollback;
private ConversationSwitcher dots;
@ -202,23 +199,32 @@ public class ConversationActivity extends Activity implements ServiceConnection,
EditText input = (EditText) findViewById(R.id.input);
input.setOnKeyListener(inputKeyListener);
switcher = (ViewSwitcher) findViewById(R.id.switcher);
pager = (ViewPager) findViewById(R.id.pager);
dots = (ConversationSwitcher) findViewById(R.id.dots);
dots.setServer(server);
deckAdapter = new DeckAdapter();
deck = (Gallery) findViewById(R.id.deck);
deck.setOnItemSelectedListener(new ConversationSelectedListener(this, server, (TextView) findViewById(R.id.title), dots));
deck.setAdapter(deckAdapter);
deck.setOnItemClickListener(new ConversationClickListener(deckAdapter, switcher));
deck.setBackgroundDrawable(new NonScalingBackgroundDrawable(this, deck, R.drawable.background));
pagerAdapter = new ConversationPagerAdapter();
pager.setAdapter(pagerAdapter);
pager.setPageMargin(5);
pager.setOnPageChangeListener(
new ConversationSelectedListener(
this,
server,
(TextView) findViewById(R.id.title),
pagerAdapter,
dots
)
);
pager.setBackgroundDrawable(new NonScalingBackgroundDrawable(this, pager, R.drawable.background));
historySize = settings.getHistorySize();
if (server.getStatus() == Status.PRE_CONNECTING) {
server.clearConversations();
deckAdapter.clearConversations();
pagerAdapter.clearConversations();
server.getConversation(ServerInfo.DEFAULT_NAME).setHistorySize(historySize);
}
@ -313,14 +319,14 @@ public class ConversationActivity extends Activity implements ServiceConnection,
// Fill view with messages that have been buffered while paused
for (Conversation conversation : mConversations) {
String name = conversation.getName();
mAdapter = deckAdapter.getItemAdapter(name);
mAdapter = pagerAdapter.getItemAdapter(name);
if (mAdapter != null) {
mAdapter.addBulkMessages(conversation.getBuffer());
conversation.clearBuffer();
} else {
// Was conversation created while we were paused?
if (deckAdapter.getPositionByName(name) == -1) {
if (pagerAdapter.getPositionByName(name) == -1) {
onNewConversation(name);
}
}
@ -336,11 +342,11 @@ public class ConversationActivity extends Activity implements ServiceConnection,
}
// Remove views for conversations that ended while we were paused
int numViews = deckAdapter.getCount();
int numViews = pagerAdapter.getCount();
if (numViews > mConversations.size()) {
for (int i = 0; i < numViews; ++i) {
if (!mConversations.contains(deckAdapter.getItem(i))) {
deckAdapter.removeItem(i--);
if (!mConversations.contains(pagerAdapter.getItem(i))) {
pagerAdapter.removeConversation(i--);
--numViews;
}
}
@ -379,33 +385,6 @@ public class ConversationActivity extends Activity implements ServiceConnection,
unregisterReceiver(serverReceiver);
}
/**
* On save instance state (e.g. before a configuration change)
*/
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
if (deckAdapter.isSwitched()) {
outState.putBoolean("isSwitched", deckAdapter.isSwitched());
outState.putString("switchedName", deckAdapter.getSwitchedName());
}
}
/**
* On restore instance state (e.g. after a configuration change)
*/
@Override
protected void onRestoreInstanceState(Bundle inState)
{
super.onRestoreInstanceState(inState);
if (inState.getBoolean("isSwitched")) {
deckAdapter.setSwitched(inState.getString("switchedName"), null);
}
}
/**
* On service connected
*/
@ -477,7 +456,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
break;
case R.id.close:
Conversation conversationToClose = deckAdapter.getItem(deck.getSelectedItemPosition());
Conversation conversationToClose = pagerAdapter.getItem(pager.getCurrentItem());
// Make sure we part a channel when closing the channel conversation
if (conversationToClose.getType() == Conversation.TYPE_CHANNEL) {
binder.getService().getConnection(serverId).partChannel(conversationToClose.getName());
@ -495,15 +474,15 @@ public class ConversationActivity extends Activity implements ServiceConnection,
break;
case R.id.users:
Conversation conversationForUserList = deckAdapter.getItem(deck.getSelectedItemPosition());
Conversation conversationForUserList = pagerAdapter.getItem(pager.getCurrentItem());
if (conversationForUserList.getType() == Conversation.TYPE_CHANNEL) {
Intent intent = new Intent(this, UsersActivity.class);
intent.putExtra(
Extra.USERS,
binder.getService().getConnection(server.getId()).getUsersAsStringArray(
conversationForUserList.getName()
)
);
Extra.USERS,
binder.getService().getConnection(server.getId()).getUsersAsStringArray(
conversationForUserList.getName()
)
);
startActivityForResult(intent, REQUEST_CODE_USERS);
} else {
Toast.makeText(this, getResources().getString(R.string.only_usable_from_channel), Toast.LENGTH_SHORT).show();
@ -516,7 +495,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
/**
* Get server object assigned to this activity
*
*
* @return the server object
*/
public Server getServer()
@ -538,7 +517,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
return;
}
MessageListAdapter adapter = deckAdapter.getItemAdapter(target);
MessageListAdapter adapter = pagerAdapter.getItemAdapter(target);
while(conversation.hasBufferedMessages()) {
Message message = conversation.pollBufferedMessage();
@ -574,14 +553,18 @@ public class ConversationActivity extends Activity implements ServiceConnection,
{
createNewConversation(target);
if (!deckAdapter.isSwitched()) {
// Scroll to new conversation
deck.setSelection(deckAdapter.getCount() - 1);
}
pager.setCurrentItem(pagerAdapter.getCount() - 1);
}
/**
* Create a new conversation in the pager adapter for the
* given target conversation.
*
* @param target
*/
public void createNewConversation(String target)
{
deckAdapter.addItem(server.getConversation(target));
pagerAdapter.addConversation(server.getConversation(target));
}
/**
@ -590,18 +573,17 @@ public class ConversationActivity extends Activity implements ServiceConnection,
@Override
public void onRemoveConversation(String target)
{
deckAdapter.removeItem(target);
int position = pagerAdapter.getPositionByName(target);
if (deckAdapter.isSwitched()) {
switcher.showNext();
switcher.removeView(deckAdapter.getSwitchedView());
deckAdapter.setSwitched(null, null);
if (position != -1) {
pagerAdapter.removeConversation(position);
}
}
/**
* On topic change
*/
@Override
public void onTopicChanged(String target)
{
String selected = server.getSelectedConversation();
@ -654,8 +636,8 @@ public class ConversationActivity extends Activity implements ServiceConnection,
return;
}
binder.getService().getConnection(server.getId()).setAutojoinChannels(
server.getCurrentChannelNames()
);
server.getCurrentChannelNames()
);
server.setStatus(Status.CONNECTING);
binder.connect(server);
reconnectDialogActive = false;
@ -675,25 +657,6 @@ public class ConversationActivity extends Activity implements ServiceConnection,
}
}
/**
* On key down
*
* XXX: As we only track the back key: Android >= 2.0 will call a method called onBackPressed()
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
if (deckAdapter.isSwitched()) {
MessageListView canvas = (MessageListView) deckAdapter.getView(deckAdapter.getPositionByName(deckAdapter.getSwitchedName()), null, switcher);
canvas.setSwitched(false);
deckAdapter.setSwitched(null, null);
return true;
}
}
return super.onKeyDown(keyCode, event);
}
/**
* On activity result
*/
@ -746,11 +709,11 @@ public class ConversationActivity extends Activity implements ServiceConnection,
String nicknameWithoutPrefix = nickname;
while (
nicknameWithoutPrefix.startsWith("@") ||
nicknameWithoutPrefix.startsWith("+") ||
nicknameWithoutPrefix.startsWith(".") ||
nicknameWithoutPrefix.startsWith("%")
) {
nicknameWithoutPrefix.startsWith("@") ||
nicknameWithoutPrefix.startsWith("+") ||
nicknameWithoutPrefix.startsWith(".") ||
nicknameWithoutPrefix.startsWith("%")
) {
// Strip prefix(es) now
nicknameWithoutPrefix = nicknameWithoutPrefix.substring(1);
}
@ -776,10 +739,10 @@ public class ConversationActivity extends Activity implements ServiceConnection,
server.addConversation(query);
Intent intent = Broadcast.createConversationIntent(
Broadcast.CONVERSATION_NEW,
server.getId(),
nicknameWithoutPrefix
);
Broadcast.CONVERSATION_NEW,
server.getId(),
nicknameWithoutPrefix
);
binder.getService().sendBroadcast(intent);
}
break;
@ -830,7 +793,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
scrollback.addMessage(text);
Conversation conversation = deckAdapter.getItem(deck.getSelectedItemPosition());
Conversation conversation = pagerAdapter.getItem(pager.getCurrentItem());
if (conversation != null) {
if (!text.trim().startsWith("/")) {
@ -907,14 +870,14 @@ public class ConversationActivity extends Activity implements ServiceConnection,
}
// Log.d("Yaaic", "Trying to complete nick: " + word);
Conversation conversationForUserList = deckAdapter.getItem(deck.getSelectedItemPosition());
Conversation conversationForUserList = pagerAdapter.getItem(pager.getCurrentItem());
String[] users = null;
if (conversationForUserList.getType() == Conversation.TYPE_CHANNEL) {
users = binder.getService().getConnection(server.getId()).getUsersAsStringArray(
conversationForUserList.getName()
);
conversationForUserList.getName()
);
}
// go through users and add matches
@ -987,7 +950,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
/**
* Remove the status char off the front of a nick if one is present
*
*
* @param nick
* @return nick without statuschar
*/
@ -995,7 +958,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
{
/* Discard status characters */
if (nick.startsWith("@") || nick.startsWith("+")
|| nick.startsWith("%")) {
|| nick.startsWith("%")) {
nick = nick.substring(1);
}
return nick;

View File

@ -17,31 +17,33 @@ 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.HashMap;
import java.util.LinkedList;
import org.yaaic.listener.MessageClickListener;
import org.yaaic.model.Conversation;
import org.yaaic.view.MessageListView;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
/**
* The adapter for the "DeckView"
*
* Adapter for displaying a pager of conversations.
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class DeckAdapter extends BaseAdapter
public class ConversationPagerAdapter extends PagerAdapter
{
private LinkedList<ConversationInfo> conversations;
private MessageListView currentView;
private String currentChannel;
private final HashMap<Integer, View> views;
/**
* Container class to remember conversation and view association.
*/
public class ConversationInfo {
public Conversation conv;
public MessageListAdapter adapter;
@ -55,44 +57,51 @@ public class DeckAdapter extends BaseAdapter
}
/**
* Create a new DeckAdapter instance
* Create a new {@link ConversationPagerAdapter} instance.
*/
public DeckAdapter()
{
public ConversationPagerAdapter() {
conversations = new LinkedList<ConversationInfo>();
views = new HashMap<Integer, View>();
}
/**
* Clear conversations
* Add a conversation to the adapter.
*
* @param conversation
*/
public void clearConversations()
{
conversations = new LinkedList<ConversationInfo>();
public void addConversation(Conversation conversation) {
conversations.add(new ConversationInfo(conversation));
notifyDataSetChanged();
}
/**
* Get number of item
* Remove the conversation at the given position from the adapter.
*
* @param position
*/
public void removeConversation(int position) {
conversations.remove(position);
notifyDataSetChanged();
}
/**
* Get position of given item.
*/
@Override
public int getCount()
public int getItemPosition(Object object)
{
return conversations.size();
}
/**
* Get ConversationInfo on item at position
*/
private ConversationInfo getItemInfo(int position) {
if (position >= 0 && position < conversations.size()) {
return conversations.get(position);
if (views.containsKey(object)) {
return POSITION_UNCHANGED;
}
return null;
return POSITION_NONE;
}
/**
* Get item at position
*/
@Override
public Conversation getItem(int position)
{
ConversationInfo convInfo = getItemInfo(position);
@ -104,11 +113,13 @@ public class DeckAdapter extends BaseAdapter
}
/**
* Get MessageListAdapter belonging to a conversation
* Get the adapter of the {@link MessageListView} at the given position.
*
* @param position Position of the conversation in the deck
* @param position
* @return
*/
public MessageListAdapter getItemAdapter(int position) {
public MessageListAdapter getItemAdapter(int position)
{
ConversationInfo convInfo = getItemInfo(position);
if (convInfo != null) {
return convInfo.adapter;
@ -118,39 +129,32 @@ public class DeckAdapter extends BaseAdapter
}
/**
* Get MessageListAdapter belonging to a conversation
* Get the adapter of the {@link MessageListView} for the conversation
* with the given name.
*
* @param name Name of the conversation
* @param name
* @return
*/
public MessageListAdapter getItemAdapter(String name) {
public MessageListAdapter getItemAdapter(String name)
{
return getItemAdapter(getPositionByName(name));
}
/**
* Get id of item at position
* Get ConversationInfo on item at position
*
* @param position
*/
@Override
public long getItemId(int position)
{
return position;
}
/**
* Add an item
*
* @param channel Name of the channel
* @param view The view object
*/
public void addItem(Conversation conversation)
{
conversations.add(new ConversationInfo(conversation));
notifyDataSetChanged();
private ConversationInfo getItemInfo(int position) {
if (position >= 0 && position < conversations.size()) {
return conversations.get(position);
}
return null;
}
/**
* Get an item by the channel's name
*
*
* @param channel
* @return The item
*/
@ -170,102 +174,62 @@ public class DeckAdapter extends BaseAdapter
}
/**
* Remove an item
*
* @param position
* Remove all conversations.
*/
public void removeItem(int position)
public void clearConversations()
{
if (position >= 0 && position < conversations.size()) {
conversations.remove(position);
notifyDataSetChanged();
}
conversations = new LinkedList<ConversationInfo>();
}
/**
* Remove an item
*
* @param target
*/
public void removeItem(String target)
{
removeItem(getPositionByName(target));
}
/**
* Set single channel view
*
* @param switched
*/
public void setSwitched(String channel, MessageListView current)
{
currentChannel = channel;
currentView = current;
}
/**
* Get single channel view
*
* @return
*/
public MessageListView getSwitchedView()
{
return currentView;
}
/**
* Get name of channel (single channel view)
*
* @return
*/
public String getSwitchedName()
{
return currentChannel;
}
/**
* Has the view been switched to single channel view?
*
* @return view true if view is in single channel view, false otherwise
*/
public boolean isSwitched()
{
return currentChannel != null;
}
/**
* Get view at given position
* Get number of conversations from this adapter.
*/
@Override
public View getView(int position, View convertView, ViewGroup parent)
public int getCount()
{
ConversationInfo convInfo = getItemInfo(position);
// Market stack traces prove that sometimes we get a null converstion
// because the collection changed while a view is requested for an
// item that does not exist anymore... so we just need to reply with
// some kind of view here.
if (convInfo == null || convInfo.conv == null) {
return new TextView(parent.getContext());
}
if (convInfo.view != null) {
return convInfo.view;
} else {
return renderConversation(convInfo, parent);
}
return conversations.size();
}
/**
* Render a conversation view (MessageListView)
*
* @param channel The conversation of the view
* @param parent The parent view (context)
* @return The rendered MessageListView
* Determines whether a page View is associated with a specific key object.
*/
private MessageListView renderConversation(ConversationInfo convInfo, ViewGroup parent)
@Override
public boolean isViewFromObject(View view, Object object)
{
MessageListView list = new MessageListView(parent.getContext(), parent);
return view == object;
}
/**
* Create a view object for the conversation at the given position.
*/
@Override
public Object instantiateItem(View collection, int position) {
// ConversationInfo convInfo = getItemInfo(position);
ConversationInfo convInfo = conversations.get(position);
View view;
if (convInfo.view != null) {
view = convInfo.view;
} else {
view = renderConversation(convInfo, collection);
}
views.put(position, view);
((ViewPager) collection).addView(view);
return view;
}
/**
* Render the given conversation and return the new view.
*
* @param convInfo
* @param parent
* @return
*/
private MessageListView renderConversation(ConversationInfo convInfo, View parent)
{
MessageListView list = new MessageListView(parent.getContext());
convInfo.view = list;
list.setOnItemClickListener(MessageClickListener.getInstance());
@ -279,11 +243,15 @@ public class DeckAdapter extends BaseAdapter
list.setAdapter(adapter);
list.setSelection(adapter.getCount() - 1); // scroll to bottom
if (convInfo.conv.getName().equals(currentChannel)) {
list.setSwitched(true);
currentView = list;
}
return list;
}
/**
* Remove the given view from the adapter and collection.
*/
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
views.remove(position);
}
}

View File

@ -1,66 +0,0 @@
/*
Yaaic - Yet Another Android IRC Client
Copyright 2009-2011 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.listener;
import org.yaaic.adapter.DeckAdapter;
import org.yaaic.model.Conversation;
import org.yaaic.view.MessageListView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ViewSwitcher;
/**
* Listener for clicks on conversations
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class ConversationClickListener implements OnItemClickListener
{
private final DeckAdapter adapter;
private final ViewSwitcher switcher;
/**
* Create a new ConversationClickListener
*
* @param adapter
* @param switcher
*/
public ConversationClickListener(DeckAdapter adapter, ViewSwitcher switcher)
{
this.adapter = adapter;
this.switcher = switcher;
}
/**
* On conversation item clicked
*/
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id)
{
Conversation conversation = adapter.getItem(position);
MessageListView canvas = (MessageListView) adapter.getView(position, null, switcher);
canvas.setSwitched(true);
adapter.setSwitched(conversation.getName(), canvas);
}
}

View File

@ -20,61 +20,63 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.yaaic.listener;
import org.yaaic.adapter.ConversationPagerAdapter;
import org.yaaic.irc.IRCService;
import org.yaaic.model.Channel;
import org.yaaic.model.Conversation;
import org.yaaic.model.Server;
import org.yaaic.view.ConversationSwitcher;
import org.yaaic.irc.IRCService;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.TextView;
import android.content.Context;
import android.content.Intent;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.widget.TextView;
/**
* Listener for conversation selections
*
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class ConversationSelectedListener implements OnItemSelectedListener
public class ConversationSelectedListener implements OnPageChangeListener
{
private final Context ctx;
private final Server server;
private final TextView titleView;
private final ConversationSwitcher switcher;
private final ConversationPagerAdapter adapter;
/**
* Create a new ConversationSelectedListener
*
*
* @param server
* @param titleView
*/
public ConversationSelectedListener(Context ctx, Server server, TextView titleView, ConversationSwitcher switcher)
public ConversationSelectedListener(Context ctx, Server server, TextView titleView, ConversationPagerAdapter adapter, ConversationSwitcher switcher)
{
this.ctx = ctx;
this.server = server;
this.titleView = titleView;
this.switcher = switcher;
this.adapter = adapter;
}
/**
* On conversation selected/focused
* On page has been selected.
*/
@Override
public void onItemSelected(AdapterView<?> deck, View view, int position, long id)
public void onPageSelected(int position)
{
Conversation conversation = (Conversation) deck.getItemAtPosition(position);
Conversation conversation = adapter.getItem(position);
if (conversation != null && conversation.getType() != Conversation.TYPE_SERVER) {
StringBuilder sb = new StringBuilder();
sb.append(server.getTitle() + " - " + conversation.getName());
if (conversation.getType() == Conversation.TYPE_CHANNEL && !((Channel)conversation).getTopic().equals(""))
if (conversation.getType() == Conversation.TYPE_CHANNEL && !((Channel)conversation).getTopic().equals("")) {
sb.append(" - " + ((Channel)conversation).getTopic());
}
titleView.setText(sb.toString());
} else {
onNothingSelected(deck);
titleView.setText(server.getTitle());
}
// Remember selection
@ -101,11 +103,18 @@ public class ConversationSelectedListener implements OnItemSelectedListener
}
/**
* On no conversation selected/focused
* On scroll state of pager has been chanaged.
*/
@Override
public void onNothingSelected(AdapterView<?> deck)
public void onPageScrollStateChanged(int state)
{
}
/**
* On page has been scrolled.
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
titleView.setText(server.getTitle());
}
}

View File

@ -1,60 +0,0 @@
/*
Yaaic - Yet Another Android IRC Client
Copyright 2009-2011 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 android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Gallery;
/**
* Conversation gallery for horizontal scrolling
*
* @author Thomas Martitz
*/
public class ConversationGallery extends Gallery
{
/**
* Create a new conversation gallery
*
* @param context
* @param attrs
*/
public ConversationGallery(Context context, AttributeSet attrs)
{
super(context, attrs);
}
/**
* On Fling: Reduce sensitivity of the channel gallery view
*/
@Override
public boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
/* Reduce sensitivity based on f(x) = x * 0.925^y with y = (|x/500| - 1)
* The goal is to reduce higher velocities stronger than low ones
* 500 is the base, i.e. it will not reduced. */
final float fexp = Math.abs(velocityX / 500.0f) - 1;
velocityX *= Math.pow(0.925, fexp);
return super.onFling(e1, e2, velocityX, velocityY);
}
}

View File

@ -33,7 +33,7 @@ import android.view.View;
/**
* The ConversationSwitcher - The small funny dots at the bottom ;)
*
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class ConversationSwitcher extends View
@ -43,7 +43,7 @@ public class ConversationSwitcher extends View
/**
* Create a new ConversationSwitcher
*
*
* @param context The Context the view is running in, through which it can access the current theme, resources, etc.
*/
public ConversationSwitcher(Context context, AttributeSet attributes)
@ -56,7 +56,7 @@ public class ConversationSwitcher extends View
/**
* Set the server whos conversations should be displayed
*
*
* @param server
*/
public void setServer(Server server)
@ -66,7 +66,7 @@ public class ConversationSwitcher extends View
/**
* Measure the size of the view
*
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/

View File

@ -25,46 +25,27 @@ import org.yaaic.adapter.MessageListAdapter;
import org.yaaic.listener.MessageClickListener;
import android.content.Context;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Gallery;
import android.widget.ListView;
/**
* A customized ListView for Messages
*
*
* @author Sebastian Kaspari <sebastian@yaaic.org>
*/
public class MessageListView extends ListView
{
private boolean switched = false;
private final View parent;
private int parentWidth;
private int parentHeight;
private final int padding;
private final int paddingWide;
/**
* Create a new MessageListView
*
*
* @param context
*/
public MessageListView(Context context, View parent)
public MessageListView(Context context)
{
super(context);
this.parent = parent;
setOnItemClickListener(MessageClickListener.getInstance());
parentWidth = parent.getWidth();
parentHeight = parent.getHeight();
setDivider(null);
setLayoutParams(new Gallery.LayoutParams(
parentWidth*85/100,
parentHeight
));
setBackgroundResource(R.layout.rounded);
setCacheColorHint(0xee000000);
@ -74,52 +55,17 @@ public class MessageListView extends ListView
// Scale padding by screen density
float density = context.getResources().getDisplayMetrics().density;
padding = (int)(5 * density);
paddingWide = (int)(12 * density);
int padding = (int) (5 * density);
setPadding(padding, padding, padding, 0);
}
/**
* Handle touch screen motion events
*/
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (!switched) {
// We delegate the touch events to the underlying view
return false;
} else {
return super.onTouchEvent(event);
}
}
/**
* On draw
*/
@Override
protected void onDraw(Canvas canvas)
{
if (parent.getWidth() != parentWidth || parent.getHeight() != parentHeight) {
// parent size changed, resizing this child too
parentWidth = parent.getWidth();
parentHeight = parent.getHeight();
if (!switched) {
setLayoutParams(new Gallery.LayoutParams(
parentWidth*85/100,
parentHeight
));
}
}
super.onDraw(canvas);
// XXX: This should be dynamically
setTranscriptMode(TRANSCRIPT_MODE_ALWAYS_SCROLL);
}
/**
* Get the adapter of this MessageListView
* (Helper to avoid casting)
*
*
* @return The MessageListAdapter
*/
@Override
@ -127,23 +73,4 @@ public class MessageListView extends ListView
{
return (MessageListAdapter) super.getAdapter();
}
/**
* Set whether this conversation is switched (taking up all of deck's space
* and handling touch events itself)
*/
public void setSwitched(boolean switched)
{
this.switched = switched;
if (switched) {
setLayoutParams(new Gallery.LayoutParams(Gallery.LayoutParams.FILL_PARENT, Gallery.LayoutParams.FILL_PARENT));
setTranscriptMode(TRANSCRIPT_MODE_NORMAL);
setPadding(paddingWide, padding, paddingWide, 0);
} else {
setLayoutParams(new Gallery.LayoutParams(parentWidth*85/100, parentHeight));
setTranscriptMode(TRANSCRIPT_MODE_ALWAYS_SCROLL);
setPadding(padding, padding, padding, 0);
}
}
}