Fotoly Android Template

Create your social photo editing app for Android

Have you seen how good the camera on an Sony Xperia Z1 is? Take our word for it, it’s amazing! So why not be one of the first to create an photo editing and sharing app to take advantage of these these amazing Android camera devices.  The Fotoly Android app template features beautiful, crisp custom Android style artwork and is fully optimised for Android Lollipop. It has views for taking images and video, editing & applying filters and sharing with friends over social networks. Like Snapchat with better editing, or Instagram with better design, Fotoly template is the easiest starting point to kick off a very cool social photo app.

What’s included in this download

  • Working, Sample .apk Project Download
  • Native Java code that builds in Android Studio View Code
  • Original layered Adobe Photoshop .psd files you can edit
  • 25+ Sliced .png files
  • Extensive Documentation Download
myapptemplates Fotoly Android Template

Create your social photo editing app for Android Have you seen how good the camera on an Sony Xperia Z1 is? Take our word for it, it’s amazing! So why not be one of the first to create an photo editing and sharing app to take advantage of these these amazing Android camera devices.  The […]

  • License Details
  • Android Sample Project
  • .PNG Artwork
  • .PSD Files
  • Android 7 Nougat Optimized
  • XHDPI Support
Our iOS and Android app templates are a perfect place to start building awesome apps. Get a functional native code base, eye-catching beautiful artwork with excellent UX, icon artwork and documentation. Make your app so beautiful it can't be ignored

Friends view

Photo screen – with custom filters, video, 1:1 and custom icons

Settings screen

Swipe to navigate through filters

Instagram style timeline view – beautiful edge to edge images, like, comment and share buttons

Code Snippet

/*
 * 
 */
package com.fotoly;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

import com.fotoly.custom.CustomActivity;
import com.fotoly.ui.CameraFragment;
import com.fotoly.ui.FilterFragment;

/**
 * The Class MainActivity is launched after the Splash and it includes the Photo
 * and Video Camera and the Filter screen. Due to the conflict of Camera with
 * ViewPager, the current implementation provides the swipe effect using the
 * Gestures
 */
public class MainActivity extends CustomActivity
{

	/** The Constant SWIPE_MIN_DISTANCE. */
	private static final int SWIPE_MIN_DISTANCE = 120;

	/** The Constant SWIPE_MAX_OFF_PATH. */
	private static final int SWIPE_MAX_OFF_PATH = 250;

	/** The Constant SWIPE_THRESHOLD_VELOCITY. */
	private static final int SWIPE_THRESHOLD_VELOCITY = 200;

	/** The Constant DISPLAY_VIDEO. */
	public static final int DISPLAY_VIDEO = 2;

	/** The Constant DISPLAY_FILTER. */
	public static final int DISPLAY_FILTER = 1;

	/** The Constant DISPLAY_PHOTO. */
	public static final int DISPLAY_PHOTO = 0;

	/** The current display. */
	private int display;

	/** The gesture detector. */
	public GestureDetector gesture;

	/* (non-Javadoc)
	 * @see com.newsfeeder.custom.CustomActivity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		initSwipeViews();
		initViewComponents();
		setupContainer();
	}

	/**
	 * This method initialize the view components, assign OnClick, OnTouch and
	 * other required listeners on views.
	 */
	private void initViewComponents()
	{
		setTouchNClick(R.id.btnCapture);
		setTouchNClick(R.id.btnEffect);
		setTouchNClick(R.id.btnPic);
		setTouchNClick(R.id.tabBrightness);
		setTouchNClick(R.id.tabGrid);
		setTouchNClick(R.id.tabSetting);
		setTouchNClick(R.id.tabSuffle);
		setTouchNClick(R.id.tabTime);

		setClick(R.id.btn1);
		setClick(R.id.btn2);
		setClick(R.id.btn3);
		setClick(R.id.btn4);
		setClick(R.id.btn5);

		applyBgTheme(findViewById(R.id.vTop));
		applyBgTheme(findViewById(R.id.vBottom));

	}

	/**
	 * Initialize the view components related to swipe gesture detection.
	 */
	private void initSwipeViews()
	{
		gesture = new GestureDetector(this, gestureListner);

		OnTouchListener otl = new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event)
			{
				return gesture.onTouchEvent(event);
			}
		};
		findViewById(R.id.content_frame).setOnTouchListener(otl);
	}

	/** The swipe gesture listener. */
	private SimpleOnGestureListener gestureListner = new SimpleOnGestureListener() {
		@Override
		public boolean onFling(android.view.MotionEvent e1,
				android.view.MotionEvent e2, float velocityX, float velocityY)
		{

			if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
				return false;
			else
			{
				try
				{
					// right to left swipe
					if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
							&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
					{
						if (display != DISPLAY_VIDEO)
						{
							display++;
							setupContainer();
						}

						// left to right swipe
					}
					else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
							&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
					{
						if (display != DISPLAY_PHOTO)
						{
							display--;
							setupContainer();
						}
					}
				} catch (Exception e)
				{
					// nothing
				}
				return true;
			}

		}
	};

	/**
	 * This method can be called from any Fragment class to remove that Fragment
	 * and attach new Fragment to this activity.
	 * 
	 * @param display
	 *            the new screen to display
	 */
	public void goBackFromFragment(int display)
	{
		this.display = display;
		setupContainer();
	}

	/**
	 * Setup screen components for this activity. This method attach the
	 * required Fragment to activity and hide/show required views on screen.
	 */
	private void setupContainer()
	{
		while (getSupportFragmentManager().getBackStackEntryCount() > 0)
		{
			getSupportFragmentManager().popBackStackImmediate();
		}

		Fragment f;
		if (display != DISPLAY_FILTER)
			f = new CameraFragment();
		else
			f = new FilterFragment();
		getSupportFragmentManager().beginTransaction()
				.replace(R.id.content_frame, f).commit();

		if (display == DISPLAY_VIDEO)
		{
			findViewById(R.id.tabGrid).setVisibility(View.GONE);
			findViewById(R.id.tabTime).setVisibility(View.VISIBLE);
			findViewById(R.id.btnEffect).setVisibility(View.INVISIBLE);

			findViewById(R.id.btnCapture).setBackgroundResource(
					R.drawable.capture_vid_btn);

			TextView b = (TextView) findViewById(R.id.btn1);
			b.setVisibility(View.VISIBLE);
			b.setText("PHOTO");

			b = (TextView) findViewById(R.id.btn2);
			b.setVisibility(View.VISIBLE);
			b.setText("1:1");

			b = (TextView) findViewById(R.id.btn3);
			b.setText("VIDEO");

			b = (TextView) findViewById(R.id.btn4);
			b.setVisibility(View.INVISIBLE);

			b = (TextView) findViewById(R.id.btn5);
			b.setVisibility(View.INVISIBLE);
		}
		else
		{
			findViewById(R.id.tabGrid).setVisibility(View.VISIBLE);
			findViewById(R.id.tabTime).setVisibility(View.GONE);
			findViewById(R.id.btnEffect).setVisibility(View.VISIBLE);

			findViewById(R.id.btnCapture).setBackgroundResource(
					R.drawable.capture_pic_btn);

			TextView b = (TextView) findViewById(R.id.btn1);
			b.setVisibility(View.INVISIBLE);

			if (display == DISPLAY_PHOTO)
			{
				b = (TextView) findViewById(R.id.btn2);
				b.setVisibility(View.INVISIBLE);

				b = (TextView) findViewById(R.id.btn3);
				b.setText("PHOTO");

				b = (TextView) findViewById(R.id.btn4);
				b.setText("1:1");
				b.setVisibility(View.VISIBLE);

				b = (TextView) findViewById(R.id.btn5);
				b.setText("VIDEO");
				b.setVisibility(View.VISIBLE);
			}
			else
			{
				b = (TextView) findViewById(R.id.btn2);
				b.setText("PHOTO");
				b.setVisibility(View.VISIBLE);

				b = (TextView) findViewById(R.id.btn3);
				b.setText("1:1");

				b = (TextView) findViewById(R.id.btn4);
				b.setText("VIDEO");
				b.setVisibility(View.VISIBLE);

				b = (TextView) findViewById(R.id.btn5);
				b.setVisibility(View.INVISIBLE);
			}
		}

	}

	/* (non-Javadoc)
	 * @see com.fotoly.custom.CustomActivity#onClick(android.view.View)
	 */
	@Override
	public void onClick(View v)
	{
		super.onClick(v);

		if (display != DISPLAY_PHOTO
				&& (v.getId() == R.id.btnPic || v.getId() == R.id.btn1))
		{
			display = DISPLAY_PHOTO;
			setupContainer();
		}
		else if (v.getId() == R.id.btn2)
		{
			if (display == DISPLAY_VIDEO)
			{
				display = DISPLAY_FILTER;
				setupContainer();
			}
			else if (display == DISPLAY_FILTER)
			{
				display = DISPLAY_PHOTO;
				setupContainer();
			}
		}
		else if (v.getId() == R.id.btn4)
		{
			if (display == DISPLAY_PHOTO)
			{
				display = DISPLAY_FILTER;
				setupContainer();
			}
			else if (display == DISPLAY_FILTER)
			{
				display = DISPLAY_VIDEO;
				setupContainer();
			}
		}
		else if (v.getId() == R.id.btn5 && display == DISPLAY_PHOTO)
		{
			display = DISPLAY_VIDEO;
			setupContainer();
		}
		else if (display != DISPLAY_FILTER && v.getId() == R.id.btnEffect)
		{
			display = DISPLAY_FILTER;
			setupContainer();
		}
		else if (v.getId() == R.id.btnCapture)
		{
			if (display == DISPLAY_FILTER)
			{
				display = DISPLAY_PHOTO;
				setupContainer();
			}
			else
				startActivity(new Intent(this, Share.class));
		}
		else if (v.getId() == R.id.tabSetting)
		{
			startActivity(new Intent(this, Settings.class));
		}
	}

}

Template Benefits

  • Android 7 Nougat ready
  • Beautiful, minimal design with excellent UX flow
  • Ready to build and customise right away in Android Studio
  • Prebuilt functionality saves you hundreds of hours of designing, programming, and testing
  • Adheres to Android Design Guidelines for easier app approval
  • The easiest way to create your own app!