Kaydet (Commit) 1e680128 authored tarafından Artur Dryomov's avatar Artur Dryomov Kaydeden (comit) Michael Meeks

Add a basic slides grid UI.

The slides adapter is using the ViewHolder pattern and view recycling to
improve performance.

Change-Id: I8f922799dc3af73e9ecaec92ca91eb38e8a784c0
üst 8e236acf
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="@android:color/transparent" />
<stroke
android:width="1dp"
android:color="@color/stroke_slide"/>
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1.5dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/grid_slides"
android:columnWidth="@dimen/width_slides_grid_column"
android:horizontalSpacing="@dimen/spacing_slides_grid"
android:verticalSpacing="@dimen/spacing_slides_grid"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:scrollbarStyle="outsideOverlay"
android:gravity="center"
android:padding="@dimen/padding_slides_grid"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="@dimen/padding_slide"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_slide_preview"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:background="@drawable/background_grid_slide"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text_slide_index"
android:background="@color/background_slide_index"
android:textColor="@android:color/white"
android:singleLine="true"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:minEms="2"
android:gravity="center_horizontal"
android:layout_height="wrap_content"/>
</RelativeLayout>
\ No newline at end of file
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
<resources> <resources>
<color name="background_action_bar">#e46f1f</color> <color name="background_action_bar">#e46f1f</color>
<color name="background_action_bar_divider">#55ffffff</color> <color name="background_action_bar_divider">#55ffffff</color>
<color name="background_slide_index">#7f000000</color>
<color name="stroke_slide">#65000000</color>
<color name="orange">#EE4400</color> <color name="orange">#EE4400</color>
<color name="grey">#303030</color> <color name="grey">#303030</color>
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<dimen name="padding_action_bar_button_drawable">8dp</dimen> <dimen name="padding_action_bar_button_drawable">8dp</dimen>
<dimen name="padding_creation_layout">16dp</dimen> <dimen name="padding_creation_layout">16dp</dimen>
<dimen name="padding_slides_grid">4dp</dimen>
<dimen name="padding_slide">4dp</dimen>
<dimen name="padding_horizontal_list_item">8dp</dimen> <dimen name="padding_horizontal_list_item">8dp</dimen>
<dimen name="padding_horizontal_connection_layout">40dp</dimen> <dimen name="padding_horizontal_connection_layout">40dp</dimen>
...@@ -16,9 +18,12 @@ ...@@ -16,9 +18,12 @@
<dimen name="margin_vertical_action_bar_divider">12dp</dimen> <dimen name="margin_vertical_action_bar_divider">12dp</dimen>
<dimen name="width_action_bar_divider">0.5dp</dimen> <dimen name="width_action_bar_divider">0.5dp</dimen>
<dimen name="width_slides_grid_column">90dp</dimen>
<dimen name="text_size_list_item">18sp</dimen> <dimen name="text_size_list_item">18sp</dimen>
<dimen name="text_size_pin">35sp</dimen> <dimen name="text_size_pin">35sp</dimen>
<dimen name="text_size_error_title">20sp</dimen> <dimen name="text_size_error_title">20sp</dimen>
<dimen name="spacing_slides_grid">4dp</dimen>
</resources> </resources>
\ No newline at end of file
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.libreoffice.impressremote;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.libreoffice.impressremote.communication.SlideShow;
public class SlidesGridAdapter extends BaseAdapter {
private final LayoutInflater mLayoutInflater;
private final SlideShow mSlideShow;
public SlidesGridAdapter(Context aContext, SlideShow aSlideShow) {
mLayoutInflater = buildLayoutInflater(aContext);
mSlideShow = aSlideShow;
}
private LayoutInflater buildLayoutInflater(Context aContext) {
return (LayoutInflater) aContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mSlideShow.getSlidesCount();
}
@Override
public Object getItem(int aPosition) {
return mSlideShow.getSlidePreview(aPosition);
}
@Override
public long getItemId(int aPosition) {
return aPosition;
}
@Override
public View getView(int aPosition, View aConvertView, ViewGroup aViewGroup) {
View aSlideView = getView(aConvertView, aViewGroup);
ViewHolder aSlideViewHolder = getViewHolder(aSlideView);
if (isSlidePreviewAvailable(aPosition)) {
aSlideViewHolder.aSlidePreview.setImageBitmap(mSlideShow.getSlidePreview(aPosition));
} else {
aSlideViewHolder.aSlidePreview.setImageResource(R.drawable.slide_unknown);
}
aSlideViewHolder.aSlideIndex.setText(buildSlideIndex(aPosition));
return aSlideView;
}
private View getView(View aConvertView, ViewGroup aViewGroup) {
if (aConvertView != null) {
return aConvertView;
}
return mLayoutInflater.inflate(R.layout.view_grid_slide, aViewGroup, false);
}
private ViewHolder getViewHolder(View aView) {
if (aView.getTag() != null) {
return (ViewHolder) aView.getTag();
}
return buildViewHolder(aView);
}
private static final class ViewHolder {
public ImageView aSlidePreview;
public TextView aSlideIndex;
}
private ViewHolder buildViewHolder(View aView) {
ViewHolder aViewHolder = new ViewHolder();
aViewHolder.aSlidePreview = (ImageView) aView.findViewById(R.id.image_slide_preview);
aViewHolder.aSlideIndex = (TextView) aView.findViewById(R.id.text_slide_index);
return aViewHolder;
}
private boolean isSlidePreviewAvailable(int aSlideIndex) {
return mSlideShow.getSlidePreview(aSlideIndex) != null;
}
private String buildSlideIndex(int aPosition) {
int aHumanSlideIndex = aPosition + 1;
return Integer.toString(aHumanSlideIndex);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.libreoffice.impressremote;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import com.actionbarsherlock.app.SherlockFragment;
import org.libreoffice.impressremote.communication.CommunicationService;
public class SlidesGridFragment extends SherlockFragment implements ServiceConnection, AdapterView.OnItemClickListener {
private CommunicationService mCommunicationService;
private BroadcastReceiver mIntentsReceiver;
public static SlidesGridFragment newInstance() {
return new SlidesGridFragment();
}
@Override
public View onCreateView(LayoutInflater aInflater, ViewGroup aContainer, Bundle aSavedInstanceState) {
return aInflater.inflate(R.layout.fragment_slides_grid, aContainer, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
bindService();
}
private void bindService() {
Intent aServiceIntent = new Intent(getActivity(), CommunicationService.class);
getActivity().bindService(aServiceIntent, this, Context.BIND_AUTO_CREATE);
}
@Override
public void onServiceConnected(ComponentName aComponentName, IBinder aBinder) {
CommunicationService.CBinder aServiceBinder = (CommunicationService.CBinder) aBinder;
mCommunicationService = aServiceBinder.getService();
mCommunicationService.getTransmitter().startPresentation();
setUpSlidesGrid();
}
private void setUpSlidesGrid() {
SlidesGridAdapter aSlidesGridAdapter = new SlidesGridAdapter(getActivity(),
mCommunicationService.getSlideShow());
getSlidesGrid().setAdapter(aSlidesGridAdapter);
getSlidesGrid().setOnItemClickListener(this);
}
private GridView getSlidesGrid() {
return (GridView) getView().findViewById(R.id.grid_slides);
}
@Override
public void onServiceDisconnected(ComponentName aComponentName) {
mCommunicationService = null;
}
@Override
public void onResume() {
super.onResume();
registerIntentsReceiver();
}
private void registerIntentsReceiver() {
mIntentsReceiver = new IntentsReceiver(this);
IntentFilter aIntentFilter = buildIntentsReceiverFilter();
getBroadcastManager().registerReceiver(mIntentsReceiver, aIntentFilter);
}
@Override
public void onItemClick(AdapterView<?> aAdapterView, View aView, int aPosition, long aId) {
mCommunicationService.getTransmitter().setCurrentSlide(aPosition);
}
private static final class IntentsReceiver extends BroadcastReceiver {
private final SlidesGridFragment mSlidesGridFragment;
private IntentsReceiver(SlidesGridFragment aSlidesGridFragment) {
mSlidesGridFragment = aSlidesGridFragment;
}
@Override
public void onReceive(Context aContext, Intent aIntent) {
if (Intents.Actions.SLIDE_PREVIEW.equals(aIntent.getAction())) {
mSlidesGridFragment.refreshSlidesGrid();
}
}
}
private IntentFilter buildIntentsReceiverFilter() {
IntentFilter aIntentFilter = new IntentFilter();
aIntentFilter.addAction(Intents.Actions.SLIDE_PREVIEW);
return aIntentFilter;
}
private LocalBroadcastManager getBroadcastManager() {
Context aContext = getActivity().getApplicationContext();
return LocalBroadcastManager.getInstance(aContext);
}
private void refreshSlidesGrid() {
getSlidesGrid().invalidateViews();
}
@Override
public void onPause() {
super.onPause();
unregisterIntentsReceiver();
}
private void unregisterIntentsReceiver() {
try {
getBroadcastManager().unregisterReceiver(mIntentsReceiver);
} catch (IllegalArgumentException e) {
// Receiver not registered.
// Fixed in Honeycomb: Android’s issue #6191.
}
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService();
}
private void unbindService() {
if (!isServiceBound()) {
return;
}
getActivity().unbindService(this);
}
private boolean isServiceBound() {
return mCommunicationService != null;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -58,6 +58,8 @@ public class CommunicationService extends Service implements Runnable, MessagesL ...@@ -58,6 +58,8 @@ public class CommunicationService extends Service implements Runnable, MessagesL
mServersManager = new ServersManager(this); mServersManager = new ServersManager(this);
mSlideShow = new SlideShow();
mThread = new Thread(this); mThread = new Thread(this);
mThread.start(); mThread.start();
} }
...@@ -240,7 +242,7 @@ public class CommunicationService extends Service implements Runnable, MessagesL ...@@ -240,7 +242,7 @@ public class CommunicationService extends Service implements Runnable, MessagesL
@Override @Override
public void onSlideShowStart(int aSlidesCount, int aCurrentSlideIndex) { public void onSlideShowStart(int aSlidesCount, int aCurrentSlideIndex) {
mSlideShow = new SlideShow(); mSlideShow.cleanUp();
mSlideShow.setSlidesCount(aSlidesCount); mSlideShow.setSlidesCount(aSlidesCount);
Intent aIntent = Intents.buildSlideShowRunningIntent(); Intent aIntent = Intents.buildSlideShowRunningIntent();
...@@ -251,7 +253,7 @@ public class CommunicationService extends Service implements Runnable, MessagesL ...@@ -251,7 +253,7 @@ public class CommunicationService extends Service implements Runnable, MessagesL
@Override @Override
public void onSlideShowFinish() { public void onSlideShowFinish() {
mSlideShow = new SlideShow(); mSlideShow.cleanUp();
Intent aIntent = Intents.buildSlideShowStoppedIntent(); Intent aIntent = Intents.buildSlideShowStoppedIntent();
LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent); LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
......
...@@ -33,7 +33,7 @@ public class SlideShow { ...@@ -33,7 +33,7 @@ public class SlideShow {
} }
public void setSlidesCount(int aSlidesCount) { public void setSlidesCount(int aSlidesCount) {
this.mSlidesCount = aSlidesCount; mSlidesCount = aSlidesCount;
} }
public int getSlidesCount() { public int getSlidesCount() {
...@@ -41,7 +41,7 @@ public class SlideShow { ...@@ -41,7 +41,7 @@ public class SlideShow {
} }
public void setCurrentSlideIndex(int aCurrentSlideIndex) { public void setCurrentSlideIndex(int aCurrentSlideIndex) {
this.mCurrentSlideIndex = aCurrentSlideIndex; mCurrentSlideIndex = aCurrentSlideIndex;
} }
public int getCurrentSlideIndex() { public int getCurrentSlideIndex() {
...@@ -76,6 +76,14 @@ public class SlideShow { ...@@ -76,6 +76,14 @@ public class SlideShow {
public Timer getTimer() { public Timer getTimer() {
return mTimer; return mTimer;
} }
public void cleanUp() {
mSlidesCount = 0;
mCurrentSlideIndex = 0;
mSlidePreviews.clear();
mSlideNotes.clear();
}
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment