Fork and kotlin port.
This commit is contained in:
@ -0,0 +1,24 @@
|
||||
package bou.amine.apps.photoviewproject
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("bou.amine.apps.photoviewproject", appContext.packageName)
|
||||
}
|
||||
}
|
38
sample/src/main/AndroidManifest.xml
Normal file
38
sample/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity android:name=".LauncherActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".SimpleSampleActivity" />
|
||||
|
||||
<activity android:name=".ViewPagerActivity" />
|
||||
|
||||
<activity android:name=".RotationSampleActivity" />
|
||||
|
||||
<activity android:name=".PicassoSampleActivity" />
|
||||
|
||||
<activity android:name=".ActivityTransitionActivity" />
|
||||
|
||||
<activity android:name=".ActivityTransitionToActivity" />
|
||||
|
||||
<activity android:name=".ImmersiveActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,60 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011, 2012 Chris Banes.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class ActivityTransitionActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_transition);
|
||||
|
||||
RecyclerView list = findViewById(R.id.list);
|
||||
list.setLayoutManager(new GridLayoutManager(this, 2));
|
||||
ImageAdapter imageAdapter = new ImageAdapter(new ImageAdapter.Listener() {
|
||||
@Override
|
||||
public void onImageClicked(View view) {
|
||||
transition(view);
|
||||
}
|
||||
});
|
||||
list.setAdapter(imageAdapter);
|
||||
}
|
||||
|
||||
private void transition(View view) {
|
||||
if (Build.VERSION.SDK_INT < 21) {
|
||||
Toast.makeText(ActivityTransitionActivity.this, "21+ only, keep out", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Intent intent = new Intent(ActivityTransitionActivity.this, ActivityTransitionToActivity.class);
|
||||
ActivityOptionsCompat options = ActivityOptionsCompat.
|
||||
makeSceneTransitionAnimation(ActivityTransitionActivity.this, view, getString(R.string.transition_test));
|
||||
startActivity(intent, options.toBundle());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
|
||||
/**
|
||||
* Activity that gets transitioned to
|
||||
*/
|
||||
public class ActivityTransitionToActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_transition_to);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
|
||||
/**
|
||||
* Hacky fix for Issue #4 and
|
||||
* http://code.google.com/p/android/issues/detail?id=18990
|
||||
* <p/>
|
||||
* ScaleGestureDetector seems to mess up the touch events, which means that
|
||||
* ViewGroups which make use of onInterceptTouchEvent throw a lot of
|
||||
* IllegalArgumentException: pointerIndex out of range.
|
||||
* <p/>
|
||||
* There's not much I can do in my code for now, but we can mask the result by
|
||||
* just catching the problem and ignoring it.
|
||||
*/
|
||||
public class HackyDrawerLayout extends DrawerLayout {
|
||||
|
||||
public HackyDrawerLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
try {
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
40
sample/src/main/java/bou/amine/apps/photoviewproject/HackyViewPager.java
Executable file
40
sample/src/main/java/bou/amine/apps/photoviewproject/HackyViewPager.java
Executable file
@ -0,0 +1,40 @@
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
/**
|
||||
* Hacky fix for Issue #4 and
|
||||
* http://code.google.com/p/android/issues/detail?id=18990
|
||||
* <p/>
|
||||
* ScaleGestureDetector seems to mess up the touch events, which means that
|
||||
* ViewGroups which make use of onInterceptTouchEvent throw a lot of
|
||||
* IllegalArgumentException: pointerIndex out of range.
|
||||
* <p/>
|
||||
* There's not much I can do in my code for now, but we can mask the result by
|
||||
* just catching the problem and ignoring it.
|
||||
*
|
||||
* @author Chris Banes
|
||||
*/
|
||||
public class HackyViewPager extends ViewPager {
|
||||
|
||||
public HackyViewPager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public HackyViewPager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
try {
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Image adapter
|
||||
*/
|
||||
public class ImageAdapter extends RecyclerView.Adapter<ImageViewHolder> {
|
||||
|
||||
Listener mListener;
|
||||
|
||||
public ImageAdapter(Listener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
ImageViewHolder holder = ImageViewHolder.inflate(parent);
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mListener.onImageClicked(view);
|
||||
}
|
||||
});
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ImageViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onImageClicked(View view);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Image in recyclerview
|
||||
*/
|
||||
public class ImageViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public static ImageViewHolder inflate(ViewGroup parent) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_image, parent, false);
|
||||
return new ImageViewHolder(view);
|
||||
}
|
||||
|
||||
public TextView mTextTitle;
|
||||
|
||||
public ImageViewHolder(View view) {
|
||||
super(view);
|
||||
mTextTitle = view.findViewById(R.id.title);
|
||||
}
|
||||
|
||||
private void bind(String title) {
|
||||
mTextTitle.setText(title);
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import bou.amine.apps.photoview.OnPhotoTapListener;
|
||||
import bou.amine.apps.photoview.PhotoView;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import static android.R.attr.uiOptions;
|
||||
|
||||
/**
|
||||
* Shows immersive image viewer
|
||||
*/
|
||||
|
||||
public class ImmersiveActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_immersive);
|
||||
|
||||
PhotoView photoView = findViewById(R.id.photo_view);
|
||||
Picasso.with(this)
|
||||
.load("http://pbs.twimg.com/media/Bist9mvIYAAeAyQ.jpg")
|
||||
.into(photoView);
|
||||
photoView.setOnPhotoTapListener(new OnPhotoTapListener() {
|
||||
@Override
|
||||
public void onPhotoTap(ImageView view, float x, float y) {
|
||||
//fullScreen();
|
||||
}
|
||||
});
|
||||
fullScreen();
|
||||
}
|
||||
|
||||
public void fullScreen() {
|
||||
|
||||
// BEGIN_INCLUDE (get_current_ui_flags)
|
||||
// The UI options currently enabled are represented by a bitfield.
|
||||
// getSystemUiVisibility() gives us that bitfield.
|
||||
int uiOptions = getWindow().getDecorView().getSystemUiVisibility();
|
||||
int newUiOptions = uiOptions;
|
||||
// END_INCLUDE (get_current_ui_flags)
|
||||
// BEGIN_INCLUDE (toggle_ui_flags)
|
||||
boolean isImmersiveModeEnabled = isImmersiveModeEnabled();
|
||||
if (isImmersiveModeEnabled) {
|
||||
Log.i("TEST", "Turning immersive mode mode off. ");
|
||||
} else {
|
||||
Log.i("TEST", "Turning immersive mode mode on.");
|
||||
}
|
||||
|
||||
// Navigation bar hiding: Backwards compatible to ICS.
|
||||
if (Build.VERSION.SDK_INT >= 14) {
|
||||
newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
|
||||
}
|
||||
|
||||
// Status bar hiding: Backwards compatible to Jellybean
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
}
|
||||
|
||||
// Immersive mode: Backward compatible to KitKat.
|
||||
// Note that this flag doesn't do anything by itself, it only augments the behavior
|
||||
// of HIDE_NAVIGATION and FLAG_FULLSCREEN. For the purposes of this sample
|
||||
// all three flags are being toggled together.
|
||||
// Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
|
||||
// Sticky immersive mode differs in that it makes the navigation and status bars
|
||||
// semi-transparent, and the UI flag does not get cleared when the user interacts with
|
||||
// the screen.
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
}
|
||||
|
||||
getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
|
||||
//END_INCLUDE (set_ui_flags)
|
||||
}
|
||||
|
||||
private boolean isImmersiveModeEnabled() {
|
||||
return ((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
|
||||
}
|
||||
|
||||
}
|
127
sample/src/main/java/bou/amine/apps/photoviewproject/LauncherActivity.java
Executable file
127
sample/src/main/java/bou/amine/apps/photoviewproject/LauncherActivity.java
Executable file
@ -0,0 +1,127 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011, 2012 Chris Banes.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class LauncherActivity extends AppCompatActivity {
|
||||
|
||||
public static final String[] options = {
|
||||
"Simple Sample",
|
||||
"ViewPager Sample",
|
||||
"Rotation Sample",
|
||||
"Picasso Sample",
|
||||
"Activity Transition Sample",
|
||||
"Immersive Sample"
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_launcher);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.setTitle(R.string.app_name);
|
||||
}
|
||||
RecyclerView recyclerView = findViewById(R.id.list);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(new ItemAdapter());
|
||||
}
|
||||
|
||||
|
||||
private static class ItemAdapter extends RecyclerView.Adapter<ItemViewHolder> {
|
||||
@Override
|
||||
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final ItemViewHolder holder = ItemViewHolder.newInstance(parent);
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Class clazz;
|
||||
|
||||
switch (holder.getAdapterPosition()) {
|
||||
default:
|
||||
case 0:
|
||||
clazz = SimpleSampleActivity.class;
|
||||
break;
|
||||
case 1:
|
||||
clazz = ViewPagerActivity.class;
|
||||
break;
|
||||
case 2:
|
||||
clazz = RotationSampleActivity.class;
|
||||
break;
|
||||
case 3:
|
||||
clazz = PicassoSampleActivity.class;
|
||||
break;
|
||||
case 4:
|
||||
clazz = ActivityTransitionActivity.class;
|
||||
break;
|
||||
case 5:
|
||||
clazz = ImmersiveActivity.class;
|
||||
}
|
||||
|
||||
Context context = holder.itemView.getContext();
|
||||
context.startActivity(new Intent(context, clazz));
|
||||
}
|
||||
});
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ItemViewHolder holder, int position) {
|
||||
holder.bind(options[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return options.length;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ItemViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public static ItemViewHolder newInstance(ViewGroup parent) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_sample, parent, false);
|
||||
return new ItemViewHolder(view);
|
||||
}
|
||||
|
||||
public TextView mTextTitle;
|
||||
|
||||
public ItemViewHolder(View view) {
|
||||
super(view);
|
||||
mTextTitle = view.findViewById(R.id.title);
|
||||
}
|
||||
|
||||
private void bind(String title) {
|
||||
mTextTitle.setText(title);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import bou.amine.apps.photoview.PhotoView;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
|
||||
public class PicassoSampleActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_simple);
|
||||
|
||||
final PhotoView photoView = findViewById(R.id.iv_photo);
|
||||
|
||||
Picasso.with(this)
|
||||
.load("http://pbs.twimg.com/media/Bist9mvIYAAeAyQ.jpg")
|
||||
.into(photoView);
|
||||
}
|
||||
}
|
102
sample/src/main/java/bou/amine/apps/photoviewproject/RotationSampleActivity.java
Executable file
102
sample/src/main/java/bou/amine/apps/photoviewproject/RotationSampleActivity.java
Executable file
@ -0,0 +1,102 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011, 2012 Chris Banes.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
||||
|
||||
import android.view.MenuItem;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import bou.amine.apps.photoview.PhotoView;
|
||||
|
||||
|
||||
public class RotationSampleActivity extends AppCompatActivity {
|
||||
|
||||
private PhotoView photo;
|
||||
private final Handler handler = new Handler();
|
||||
private boolean rotating = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_rotation_sample);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.inflateMenu(R.menu.rotation);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_rotate_10_right:
|
||||
photo.setRotationBy(10);
|
||||
return true;
|
||||
case R.id.action_rotate_10_left:
|
||||
photo.setRotationBy(-10);
|
||||
return true;
|
||||
case R.id.action_toggle_automatic_rotation:
|
||||
toggleRotation();
|
||||
return true;
|
||||
case R.id.action_reset_to_0:
|
||||
photo.setRotationTo(0);
|
||||
return true;
|
||||
case R.id.action_reset_to_90:
|
||||
photo.setRotationTo(90);
|
||||
return true;
|
||||
case R.id.action_reset_to_180:
|
||||
photo.setRotationTo(180);
|
||||
return true;
|
||||
case R.id.action_reset_to_270:
|
||||
photo.setRotationTo(270);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
photo = findViewById(R.id.iv_photo);
|
||||
photo.setImageResource(R.drawable.wallpaper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
private void toggleRotation() {
|
||||
if (rotating) {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
} else {
|
||||
rotateLoop();
|
||||
}
|
||||
rotating = !rotating;
|
||||
}
|
||||
|
||||
private void rotateLoop() {
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
photo.setRotationBy(1);
|
||||
rotateLoop();
|
||||
}
|
||||
}, 15);
|
||||
}
|
||||
}
|
193
sample/src/main/java/bou/amine/apps/photoviewproject/SimpleSampleActivity.java
Executable file
193
sample/src/main/java/bou/amine/apps/photoviewproject/SimpleSampleActivity.java
Executable file
@ -0,0 +1,193 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011, 2012 Chris Banes.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import bou.amine.apps.photoview.OnMatrixChangedListener;
|
||||
import bou.amine.apps.photoview.OnPhotoTapListener;
|
||||
import bou.amine.apps.photoview.OnSingleFlingListener;
|
||||
import bou.amine.apps.photoview.PhotoView;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class SimpleSampleActivity extends AppCompatActivity {
|
||||
|
||||
static final String PHOTO_TAP_TOAST_STRING = "Photo Tap! X: %.2f %% Y:%.2f %% ID: %d";
|
||||
static final String SCALE_TOAST_STRING = "Scaled to: %.2ff";
|
||||
static final String FLING_LOG_STRING = "Fling velocityX: %.2f, velocityY: %.2f";
|
||||
|
||||
private PhotoView mPhotoView;
|
||||
private TextView mCurrMatrixTv;
|
||||
|
||||
private Toast mCurrentToast;
|
||||
|
||||
private Matrix mCurrentDisplayMatrix = null;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_simple_sample);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.setTitle("Simple Sample");
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onBackPressed();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.inflateMenu(R.menu.main_menu);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_zoom_toggle:
|
||||
mPhotoView.setZoomable(!mPhotoView.isZoomEnabled());
|
||||
item.setTitle(mPhotoView.isZoomEnabled() ? R.string.menu_zoom_disable : R.string.menu_zoom_enable);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_fit_center:
|
||||
mPhotoView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_fit_start:
|
||||
mPhotoView.setScaleType(ImageView.ScaleType.FIT_START);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_fit_end:
|
||||
mPhotoView.setScaleType(ImageView.ScaleType.FIT_END);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_fit_xy:
|
||||
mPhotoView.setScaleType(ImageView.ScaleType.FIT_XY);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_scale_center:
|
||||
mPhotoView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_scale_center_crop:
|
||||
mPhotoView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_scale_center_inside:
|
||||
mPhotoView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
return true;
|
||||
|
||||
case R.id.menu_scale_random_animate:
|
||||
case R.id.menu_scale_random:
|
||||
Random r = new Random();
|
||||
|
||||
float minScale = mPhotoView.getMinimumScale();
|
||||
float maxScale = mPhotoView.getMaximumScale();
|
||||
float randomScale = minScale + (r.nextFloat() * (maxScale - minScale));
|
||||
mPhotoView.setScale(randomScale, item.getItemId() == R.id.menu_scale_random_animate);
|
||||
|
||||
showToast(String.format(SCALE_TOAST_STRING, randomScale));
|
||||
|
||||
return true;
|
||||
case R.id.menu_matrix_restore:
|
||||
if (mCurrentDisplayMatrix == null)
|
||||
showToast("You need to capture display matrix first");
|
||||
else
|
||||
mPhotoView.setDisplayMatrix(mCurrentDisplayMatrix);
|
||||
return true;
|
||||
case R.id.menu_matrix_capture:
|
||||
mCurrentDisplayMatrix = new Matrix();
|
||||
mPhotoView.getDisplayMatrix(mCurrentDisplayMatrix);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
mPhotoView = findViewById(R.id.iv_photo);
|
||||
mCurrMatrixTv = findViewById(R.id.tv_current_matrix);
|
||||
|
||||
Drawable bitmap = ContextCompat.getDrawable(this, R.drawable.wallpaper);
|
||||
mPhotoView.setImageDrawable(bitmap);
|
||||
|
||||
// Lets attach some listeners, not required though!
|
||||
mPhotoView.setOnMatrixChangeListener(new MatrixChangeListener());
|
||||
mPhotoView.setOnPhotoTapListener(new PhotoTapListener());
|
||||
mPhotoView.setOnSingleFlingListener(new SingleFlingListener());
|
||||
}
|
||||
|
||||
private class PhotoTapListener implements OnPhotoTapListener {
|
||||
|
||||
@Override
|
||||
public void onPhotoTap(ImageView view, float x, float y) {
|
||||
float xPercentage = x * 100f;
|
||||
float yPercentage = y * 100f;
|
||||
|
||||
showToast(String.format(PHOTO_TAP_TOAST_STRING, xPercentage, yPercentage, view == null ? 0 : view.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private void showToast(CharSequence text) {
|
||||
if (mCurrentToast != null) {
|
||||
mCurrentToast.cancel();
|
||||
}
|
||||
|
||||
mCurrentToast = Toast.makeText(SimpleSampleActivity.this, text, Toast.LENGTH_SHORT);
|
||||
mCurrentToast.show();
|
||||
}
|
||||
|
||||
private class MatrixChangeListener implements OnMatrixChangedListener {
|
||||
|
||||
@Override
|
||||
public void onMatrixChanged(RectF rect) {
|
||||
mCurrMatrixTv.setText(rect.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private class SingleFlingListener implements OnSingleFlingListener {
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
Log.d("PhotoView", String.format(FLING_LOG_STRING, velocityX, velocityY));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
73
sample/src/main/java/bou/amine/apps/photoviewproject/ViewPagerActivity.java
Executable file
73
sample/src/main/java/bou/amine/apps/photoviewproject/ViewPagerActivity.java
Executable file
@ -0,0 +1,73 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011, 2012 Chris Banes.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
package bou.amine.apps.photoviewproject;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import bou.amine.apps.photoview.PhotoView;
|
||||
|
||||
|
||||
public class ViewPagerActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_view_pager);
|
||||
ViewPager viewPager = findViewById(R.id.view_pager);
|
||||
|
||||
viewPager.setAdapter(new SamplePagerAdapter());
|
||||
}
|
||||
|
||||
static class SamplePagerAdapter extends PagerAdapter {
|
||||
|
||||
private static final int[] sDrawables = { R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper,
|
||||
R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper };
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return sDrawables.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View instantiateItem(ViewGroup container, int position) {
|
||||
PhotoView photoView = new PhotoView(container.getContext());
|
||||
photoView.setImageResource(sDrawables[position]);
|
||||
|
||||
// Now just add PhotoView to ViewPager and return it
|
||||
container.addView(photoView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||
|
||||
return photoView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
container.removeView((View) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
BIN
sample/src/main/res/drawable-nodpi/wallpaper.jpg
Executable file
BIN
sample/src/main/res/drawable-nodpi/wallpaper.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
</vector>
|
12
sample/src/main/res/layout/activity_immersive.xml
Normal file
12
sample/src/main/res/layout/activity_immersive.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<bou.amine.apps.photoview.PhotoView
|
||||
android:id="@+id/photo_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
18
sample/src/main/res/layout/activity_launcher.xml
Normal file
18
sample/src/main/res/layout/activity_launcher.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
25
sample/src/main/res/layout/activity_rotation_sample.xml
Executable file
25
sample/src/main/res/layout/activity_rotation_sample.xml
Executable file
@ -0,0 +1,25 @@
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<bou.amine.apps.photoview.PhotoView
|
||||
android:id="@+id/iv_photo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/wallpaper"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
5
sample/src/main/res/layout/activity_simple.xml
Executable file
5
sample/src/main/res/layout/activity_simple.xml
Executable file
@ -0,0 +1,5 @@
|
||||
<bou.amine.apps.photoview.PhotoView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/iv_photo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
33
sample/src/main/res/layout/activity_simple_sample.xml
Executable file
33
sample/src/main/res/layout/activity_simple_sample.xml
Executable file
@ -0,0 +1,33 @@
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<bou.amine.apps.photoview.PhotoView
|
||||
android:id="@+id/iv_photo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_current_matrix"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:background="#60000000"
|
||||
android:gravity="center"
|
||||
android:textColor="@android:color/white"/>
|
||||
|
||||
</FrameLayout>
|
5
sample/src/main/res/layout/activity_transition.xml
Executable file
5
sample/src/main/res/layout/activity_transition.xml
Executable file
@ -0,0 +1,5 @@
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
7
sample/src/main/res/layout/activity_transition_to.xml
Executable file
7
sample/src/main/res/layout/activity_transition_to.xml
Executable file
@ -0,0 +1,7 @@
|
||||
<bou.amine.apps.photoview.PhotoView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/iv_photo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/wallpaper"
|
||||
android:transitionName="@string/transition_test" />
|
6
sample/src/main/res/layout/activity_view_pager.xml
Executable file
6
sample/src/main/res/layout/activity_view_pager.xml
Executable file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<bou.amine.apps.photoviewproject.HackyViewPager
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
7
sample/src/main/res/layout/item_image.xml
Normal file
7
sample/src/main/res/layout/item_image.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ImageView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/wallpaper"/>
|
30
sample/src/main/res/layout/item_sample.xml
Normal file
30
sample/src/main/res/layout/item_sample.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/listPreferredItemHeight"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@android:color/white"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textSize="20sp"
|
||||
android:layout_margin="16dp"
|
||||
tools:text="Hello there"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@android:color/white"/>
|
||||
|
||||
</FrameLayout>
|
43
sample/src/main/res/menu/main_menu.xml
Executable file
43
sample/src/main/res/menu/main_menu.xml
Executable file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_zoom_toggle"
|
||||
android:title="@string/menu_zoom_disable"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_fit_center"
|
||||
android:title="@string/menu_scale_fit_center"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_fit_start"
|
||||
android:title="@string/menu_scale_fit_start"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_fit_end"
|
||||
android:title="@string/menu_scale_fit_end"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_fit_xy"
|
||||
android:title="@string/menu_scale_fit_xy"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_scale_center"
|
||||
android:title="@string/menu_scale_center"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_scale_center_crop"
|
||||
android:title="@string/menu_scale_center_crop"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_scale_center_inside"
|
||||
android:title="@string/menu_scale_center_inside"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_random_animate"
|
||||
android:title="@string/menu_zoom_random_animate"/>
|
||||
<item
|
||||
android:id="@+id/menu_scale_random"
|
||||
android:title="@string/menu_zoom_random"/>
|
||||
<item
|
||||
android:id="@+id/menu_matrix_restore"
|
||||
android:title="@string/menu_matrix_restore"/>
|
||||
<item
|
||||
android:id="@+id/menu_matrix_capture"
|
||||
android:title="@string/menu_matrix_capture"/>
|
||||
|
||||
</menu>
|
31
sample/src/main/res/menu/rotation.xml
Normal file
31
sample/src/main/res/menu/rotation.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_rotate_10_right"
|
||||
android:title="Rotate 10° Right"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_rotate_10_left"
|
||||
android:title="Rotate 10° Left"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_toggle_automatic_rotation"
|
||||
android:title="Toggle Automatic Rotation"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reset_to_0"
|
||||
android:title="Reset to 0"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reset_to_90"
|
||||
android:title="Reset to 90"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reset_to_180"
|
||||
android:title="Reset to 180"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reset_to_270"
|
||||
android:title="Reset to 270"/>
|
||||
</menu>
|
BIN
sample/src/main/res/mipmap-hdpi/ic_launcher.png
Executable file
BIN
sample/src/main/res/mipmap-hdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
sample/src/main/res/mipmap-mdpi/ic_launcher.png
Executable file
BIN
sample/src/main/res/mipmap-mdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
sample/src/main/res/mipmap-xhdpi/ic_launcher.png
Executable file
BIN
sample/src/main/res/mipmap-xhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
Executable file
BIN
sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
BIN
sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
BIN
sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
6
sample/src/main/res/values/colors.xml
Normal file
6
sample/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="green">#AACE30</color>
|
||||
<color name="blue">#142D3E</color>
|
||||
<color name="blue_dark">#001425</color>
|
||||
</resources>
|
19
sample/src/main/res/values/strings.xml
Executable file
19
sample/src/main/res/values/strings.xml
Executable file
@ -0,0 +1,19 @@
|
||||
<resources>
|
||||
|
||||
<string name="app_name">PhotoView Sample</string>
|
||||
<string name="menu_zoom_enable">Enable Zoom</string>
|
||||
<string name="menu_zoom_disable">Disable Zoom</string>
|
||||
<string name="menu_scale_fit_center">Change to FIT_CENTER</string>
|
||||
<string name="menu_scale_fit_start">Change to FIT_START</string>
|
||||
<string name="menu_scale_fit_end">Change to FIT_END</string>
|
||||
<string name="menu_scale_fit_xy">Change to FIT_XY</string>
|
||||
<string name="menu_scale_center">Change to CENTER</string>
|
||||
<string name="menu_scale_center_inside">Change to CENTER_INSIDE</string>
|
||||
<string name="menu_scale_center_crop">Change to CENTER_CROP</string>
|
||||
<string name="menu_zoom_random_animate">Animate scale to random value</string>
|
||||
<string name="menu_zoom_random">Set scale to random value</string>
|
||||
<string name="menu_matrix_restore">Restore Display Matrix</string>
|
||||
<string name="menu_matrix_capture">Capture Display Matrix</string>
|
||||
<string name="extract_visible_bitmap">Extract visible bitmap</string>
|
||||
|
||||
</resources>
|
13
sample/src/main/res/values/styles.xml
Normal file
13
sample/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/blue</item>
|
||||
<item name="colorPrimaryDark">@color/blue_dark</item>
|
||||
<item name="colorAccent">@color/green</item>
|
||||
|
||||
<!-- enable window content transitions -->
|
||||
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
|
||||
</style>
|
||||
</resources>
|
4
sample/src/main/res/values/transitions.xml
Normal file
4
sample/src/main/res/values/transitions.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="transition_test">test</string>
|
||||
</resources>
|
@ -0,0 +1,17 @@
|
||||
package bou.amine.apps.photoviewproject
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user