Create categories so that Hybrid Apps and messages appear in lists under a category heading.
The comment tag associated with creating categorized views is ANDROID_CUSTOMIZATION_POINT_CATEGORIZEDVIEWS.
First, determine names for the categories. Sybase recommends that you name the final category “Miscellaneous;” this adds all applications and messages that do not match a category to the Miscellaneous category. Also in this example, all applications that belong to a category must include the category name contained in their display name. For example, an application named “Financial Claim” belongs in the “Financial” category.
There are other ways to determine categories; if you know the names of the applications in advance, you can simply list all the application names that belong in each category.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:padding="6dip"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="0dip" android:layout_weight="1" android:layout_height="fill_parent"> <TextView android:id="@+id/category" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:singleLine="true" android:ellipsize="marquee" android:gravity="center_vertical" /> </LinearLayout> </LinearLayout>
public static final String[] m_asHybridAppCategories = { "Financial", "Utilities", "Miscellaneous" };
private class HybridAppAdapter extends ArrayAdapter<Object> { private String[] m_asCategories; public HybridAppAdapter( Context context, int textviewResourceId, List<Object> items, String[] categories ){ super( context, textviewResourceId, items ); m_asCategories = categories; for( int index = 0; index < m_asCategories.length; index++ ) { this.add( m_asCategories[index] ); } } @Override public View getView(int position, View convertView, ViewGroup parent) { Object oObject = this.getItem(position); View v = null; if( oObject instanceof HybridApp ) { HybridApp oHybridApp = ( HybridApp ) oObject; LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.workflows, null); if ( oHybridApp != null ) { ImageView ic = (ImageView) v.findViewById( R.id.workflow_icon ); ic.setImageResource( UiIconIndexLookup.getNormalIconIdForIndex( oHybridApp.getIconIndex() )); TextView tt = (TextView) v.findViewById(R.id.workflow_title); if (tt != null) { tt.setText( oHybridApp.getDisplayName()); } } } else { //This position is not a HybridApp, but a category heading String sString = ( String ) oObject; LayoutInflater vi = ( LayoutInflater ) getSystemService( Context.LAYOUT_INFLATER_SERVICE ); v = vi.inflate( R.layout.category, null ); if( sString != null ) { TextView tt = (TextView) v.findViewById( R.id.category ); if ( tt != null ) { tt.setText( sString ); } } } return v; } public void remove( HybridApp oApp ) { // The object to remove has a different pointer // so match it up with the one in the list for ( int i = 0; i < this.getCount(); i++ ) { Object oObject = getItem( i ); if( oObject instanceof HybridApp ) { HybridApp oTemp = ( HybridApp ) oObject; if ( oApp.getModuleId() == oTemp.getModuleId() && oApp.getVersion() == oTemp.getVersion() ) { super.remove( oTemp ); return; } } } } public void sort() { // Sorts applications by name this.sort( new Comparator<Object>() { @Override public int compare( Object oObject1, Object oObject2 ) { if( oObject1 instanceof String && oObject2 instanceof String) { String sString1 = ( String ) oObject1; String sString2 = ( String ) oObject2; for( int index = 0; index < m_asCategories.length; index++ ) { if( sString1.equals( m_asCategories[index] ) ) { return -1; } if( sString2.equals( m_asCategories[index]) ) { return 1; } } } else if( oObject1 instanceof HybridApp && oObject2 instanceof HybridApp ) { HybridApp oHybridApp1 = ( HybridApp ) oObject1; HybridApp oHybridApp2 = ( HybridApp ) oObject2; int iCategoryIndex1 = getCategoryIndex( oHybridApp1 ); int iCategoryIndex2 = getCategoryIndex( oHybridApp2 ); if( iCategoryIndex1 == iCategoryIndex2 ) { return oHybridApp1.getDisplayName().toLowerCase().compareTo( oHybridApp2.getDisplayName().toLowerCase() ); } else { return iCategoryIndex1 - iCategoryIndex2; } } else { //we have one String (category heading) and one HybridApp HybridApp oHybridApp = null; String sString = null; int iSwitch = 1; if( oObject1 instanceof HybridApp) { oHybridApp = ( HybridApp ) oObject1; sString = ( String ) oObject2; } else { oHybridApp = ( HybridApp ) oObject2; sString = ( String ) oObject1; iSwitch = -1; } int iHybridAppCategoryIndex = getCategoryIndex( oHybridApp ); int iCategoryIndex = getCategoryIndex( sString ); if( iCategoryIndex <= iHybridAppCategoryIndex ) { return 1*iSwitch; } else { return -1*iSwitch; } } return 0; } private int getCategoryIndex( String sString ) { for( int index = 0; index < m_asCategories.length; index++ ) { if( m_asCategories[index].equalsIgnoreCase( sString ) ) { return index; } } return m_asCategories.length - 1; } private int getCategoryIndex( HybridApp oHybridApp ) { for( int index = 0; index < m_asCategories.length; index++ ) { if( oHybridApp.getDisplayName().toLowerCase().indexOf( m_asCategories[index].toLowerCase() ) >= 0 ) { return index; } } return m_asCategories.length - 1; } }); } }
this.m_adapter = new HybridAppAdapter( this, R.layout.workflows, new ArrayList<Object>(Arrays.asList( HybridAppDb.getInvocableHybridApps() ) ), m_asHybridAppCategories );
public void onListItemClick(ListView oParent, View v, int iPos, long id ) { Object oObject = m_adapter.getItem( iPos ); if( oObject instanceof HybridApp ) { HybridApp oHybridApp = ( HybridApp ) oObject; Intent oIntentHybridAppContainer = new Intent( this, UiHybridAppContainer.class ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_START_MODE, Consts.START_MODE_HYBRIDAPP ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_ID, ((HybridAppDb) oHybridApp).getHybridAppId() ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_PROGRESS_TEXT, oHybridApp.getDisplayName() ); startActivityForResult( oIntentHybridAppContainer, Consts.INTENT_ID_HYBRIDAPP_CONTAINER ); } }
public void onCreateContextMenu( ContextMenu oMenu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu( oMenu, v, menuInfo ); AdapterContextMenuInfo oInfo = (AdapterContextMenuInfo) menuInfo; Object oObject = m_adapter.getItem( oInfo.position ); if( oObject instanceof Message ) { Message oMsg = ( Message ) oObject; oMenu.setHeaderTitle( oMsg.getSubject() ); oMenu.add( 0, CONTEXT_MENU_DELETE, 0, R.string.Context_Menu_Delete ); // Save the id for operations used in the context menu m_iContextMessageId = oMsg.getMessageId(); } }
public boolean onContextItemSelected( MenuItem oItem ) { if ( oItem.getItemId() == CONTEXT_MENU_DELETE ) { AdapterContextMenuInfo oInfo = (AdapterContextMenuInfo) oItem.getMenuInfo(); // The message might have been deleted while the context menu was open. // Make sure the position is still present and matches the id we expect if ( oInfo.position < m_adapter.getCount() ) { Object oObject = m_adapter.getItem( oInfo.position ); if( oObject instanceof Message ) { Message oMsg = ( Message ) oObject; if ( oMsg.getMessageId() == m_iContextMessageId ) { // Remove message from database MessageDb.delete( oMsg.getMessageId() ); } } } return true; } return false; }
private class MessageAdapter extends ArrayAdapter<Object> { String[] m_asCategories; public MessageAdapter( Context context, int textviewResourceId, ArrayList<Object> items, String[] categories ){ super( context, textviewResourceId, items ); m_asCategories = categories; for( int index = 0; index < m_asCategories.length; index++ ) { this.add( m_asCategories[index] ); } } @Override public View getView(int position, View convertView, ViewGroup parent) { Object oObject = getItem( position ); View v = null; if( oObject instanceof Message ) { Message oMsg = (Message) oObject; LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.workflowmessages, null); if ( oMsg != null ) { //set the Hybrid App message priority icon ImageView imageForPriority = (ImageView) v.findViewById( R.id.priority_icon ); if ( oMsg.getMailPriority() == AmpConsts.EMAIL_STATUS_IMPORTANCE_HIGH ) { imageForPriority.setImageResource( R.drawable.readhi ); imageForPriority.setVisibility( View.VISIBLE ); } else if ( oMsg.getMailPriority() == AmpConsts.EMAIL_STATUS_IMPORTANCE_LOW ) { imageForPriority.setImageResource( R.drawable.readlow ); imageForPriority.setVisibility( View.VISIBLE ); } else imageForPriority.setVisibility( View.GONE ); ImageView ic = (ImageView) v.findViewById( R.id.msg_icon ); if ( oMsg.isMsgProcessed() ) ic.setImageResource( UiIconIndexLookup.getProcessedIconIdForIndex( oMsg.getIconIndex())); else ic.setImageResource( UiIconIndexLookup.getNormalIconIdForIndex( oMsg.getIconIndex())); TextView tf = (TextView) v.findViewById(R.id.msg_from); TextView tt = (TextView) v.findViewById(R.id.msg_title); TextView bt = (TextView) v.findViewById(R.id.msg_datetime); if ( tf != null ) { tf.setText( oMsg.getMsgFrom() ); } if (tt != null) { tt.setText( oMsg.getSubject()); } if(bt != null){ Calendar dtReceived = Calendar.getInstance(); dtReceived.setTime( oMsg.getReceivedDate() ); Calendar dtNow = Calendar.getInstance(); if ( dtNow.get( Calendar.YEAR ) == dtReceived.get( Calendar.YEAR ) && dtNow.get( Calendar.MONTH ) == dtReceived.get( Calendar.MONTH ) && dtNow.get( Calendar.DAY_OF_MONTH ) == dtReceived.get( Calendar.DAY_OF_MONTH ) ) { bt.setText( ( new SimpleDateFormat( "hh:mm a" ) ).format( oMsg.getReceivedDate() ) ); } else { bt.setText( ( new SimpleDateFormat( "MM/dd/yy" ) ).format( oMsg.getReceivedDate() ) ); } } // Update appearance unread messages if ( tf != null && tt != null && bt != null ) { if ( !oMsg.isMsgRead() ) { // Setup view for unread message v.setBackgroundResource( R.drawable.unread_selector ); tf.setTextColor( Color.WHITE ); tf.setTypeface( null, Typeface.BOLD ); } else { // Setup view for read message v.setBackgroundResource( 0 ); TypedValue tv = new TypedValue(); getTheme().resolveAttribute( android.R.attr.textColorSecondary, tv, true ); tf.setTextColor( getResources().getColor( tv.resourceId ) ); tf.setTypeface( null, Typeface.NORMAL ); } } } } else { String sString = ( String ) oObject; LayoutInflater vi = ( LayoutInflater ) getSystemService( Context.LAYOUT_INFLATER_SERVICE ); v = vi.inflate( R.layout.category, null ); if( sString != null ) { TextView tt = (TextView) v.findViewById( R.id.category ); if ( tt != null ) { tt.setText( sString ); } } } return v; } public void sort() { // Sorts applications by name this.sort( new Comparator<Object>() { @Override public int compare( Object oObject1, Object oObject2 ) { if( oObject1 instanceof String && oObject2 instanceof String) { String sString1 = ( String ) oObject1; String sString2 = ( String ) oObject2; for( int index = 0; index < m_asCategories.length; index++ ) { if( sString1.equals( m_asCategories[index] ) ) { return -1; } if( sString2.equals( m_asCategories[index]) ) { return 1; } } } else if( oObject1 instanceof Message && oObject2 instanceof Message ) { Message oMessage1 = ( Message ) oObject1; Message oMessage2 = ( Message ) oObject2; int iCategoryIndex1 = getCategoryIndex( oMessage1 ); int iCategoryIndex2 = getCategoryIndex( oMessage2 ); if( iCategoryIndex1 == iCategoryIndex2 ) { return oMessage1.getReceivedDate().compareTo( oMessage2.getReceivedDate() ); } else { return iCategoryIndex1 - iCategoryIndex2; } } else { //we have one String (category heading) and one HybridApp Message oMessage = null; String sString = null; int iSwitch = 1; if( oObject1 instanceof Message) { oMessage = ( Message ) oObject1; sString = ( String ) oObject2; } else { oMessage = ( Message ) oObject2; sString = ( String ) oObject1; iSwitch = -1; } int iMessageCategoryIndex = getCategoryIndex( oMessage ); int iCategoryIndex = getCategoryIndex( sString ); if( iCategoryIndex <= iMessageCategoryIndex ) { return 1*iSwitch; } else { return -1*iSwitch; } } return 0; } private int getCategoryIndex( String sString ) { for( int index = 0; index < m_asCategories.length; index++ ) { if( m_asCategories[index].equalsIgnoreCase( sString ) ) { return index; } } return m_asCategories.length - 1; } private int getCategoryIndex( Message oMessage ) { MessageDb oMessageDb = (MessageDb) oMessage; if( oMessageDb != null ) { HybridApp oHybridApp = HybridAppDb.getHybridApp(oMessage.getModuleId(), oMessage.getModuleVersion()); String sModuleName = oHybridApp.getDisplayName(); if( sModuleName != null ) { for( int index = 0; index < m_asCategories.length; index++ ) { if( sModuleName.toLowerCase().indexOf( m_asCategories[index].toLowerCase() ) >= 0 ) { return index; } } } } return m_asCategories.length - 1; } }); } }
try { // ANDROID_CUSTOMIZATION_POINT_FILTERING ArrayList<Message> alMessages = MessageDb.getMessages(); ArrayList<Object> alMessagesObjects = new ArrayList( alMessages ); this.m_adapter = new MessageAdapter( this, R.layout.workflowmessages, alMessagesObjects, UiHybridAppScreen.m_asHybridAppCategories ); this.m_adapter.sort(); }
public void onListItemClick(ListView oParent, View v, int iPos, long id ) { try { Object oObject = m_adapter.getItem( iPos ); if( oObject instanceof Message ) { Message oMsg = ( Message ) oObject; // Check if Hybrid App is available HybridApp oHybridApp = HybridAppDb.getHybridApp( oMsg.getModuleId(), oMsg.getModuleVersion()); // CR668069 -Check if we can handle transform data - 1mb limit by sqllite database try { oMsg.getTransformData(); } catch ( Exception ex ) { MocaLog.getAmpHostLog().logMessage( "Failed to read transform data", MocaLog.eMocaLogLevel.Normal ); new AlertDialog.Builder( this ) .setTitle( android.R.string.dialog_alert_title ) .setMessage( R.string.IDS_MSG_ERR_MESSAGE_TOO_LARGE ) .setIcon( android.R.drawable.ic_dialog_alert ) .setPositiveButton( android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialog, int whichButton) { dialog.dismiss(); } } ) .show(); return; } // Update read flag if ( !oMsg.isMsgRead() ) { m_adapter.notifyDataSetChanged(); } // Open Hybrid App Intent oIntentHybridAppContainer = new Intent( this, UiHybridAppContainer.class ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_START_MODE, Consts.START_MODE_MESSAGE ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_MSG_ID, oMsg.getMessageId() ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_MODULE_ID, oMsg.getModuleId() ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_MODULE_VERSION, oMsg.getModuleVersion() ); oIntentHybridAppContainer.putExtra( Consts.INTENT_PARAM_HYBRIDAPP_PROGRESS_TEXT, oMsg.getSubject() ); startActivityForResult( oIntentHybridAppContainer, Consts.INTENT_ID_HYBRIDAPP_CONTAINER ); } } catch( Exception ex ) { MocaLog.getAmpHostLog().logMessage( "Failed to open message. Caught exception - " + ex.getMessage(), MocaLog.eMocaLogLevel.Normal ); } }