implemented sync process

pull/5/head
Felix Prahl-Kamps 2018-06-16 17:38:59 +02:00
parent b49cc7a66f
commit 70dbbeb479
21 changed files with 698 additions and 141 deletions

View File

@ -22,7 +22,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
@ -31,4 +31,5 @@ dependencies {
implementation 'com.android.volley:volley:1.1.0'
implementation 'com.github.kenglxn.QRGen:android:2.4.0'
implementation 'com.google.android.gms:play-services-vision:15.0.2'
}

View File

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.overview.wg.its.mispauth">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
@ -26,6 +27,7 @@
android:parentActivityName=".activity.MainActivity"/>
<activity
android:screenOrientation="portrait"
android:name=".activity.SyncActivity"
android:label="@string/title_activity_sync"
android:parentActivityName=".activity.MainActivity"/>

View File

@ -1,35 +1,38 @@
package de.overview.wg.its.mispauth.activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import com.android.volley.VolleyError;
import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.auxiliary.OrganisationDialog;
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
import de.overview.wg.its.mispauth.fragment.ScanQrFragment;
import de.overview.wg.its.mispauth.fragment.ShowQrFragment;
import de.overview.wg.its.mispauth.fragment.SyncStartFragment;
import de.overview.wg.its.mispauth.fragment.UploadFragment;
import de.overview.wg.its.mispauth.model.Organisation;
import de.overview.wg.its.mispauth.network.MispRequest;
import de.overview.wg.its.mispauth.custom_viewpager.ExtendedViewPager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class SyncActivity extends AppCompatActivity {
private static final String TAG = "DEBUG";
private PreferenceManager preferenceManager;
private static final int PAGE_COUNT = 3;
private ExtendedViewPager viewPager;
private PagerAdapter pagerAdapter;
private LinearLayout bottomLayout;
private Button prevButton, nextButton;
private int partnerChoice = -1;
private String scannedQrString = "";
private int currentFragmentPosition = 0;
@Override
@ -37,107 +40,131 @@ public class SyncActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
preferenceManager = PreferenceManager.Instance(this);
setupViewPager();
nextButton = findViewById(R.id.nextButton);
prevButton = findViewById(R.id.backButton);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getFragment(currentFragmentPosition + 1, true);
}
});
prevButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getFragment(currentFragmentPosition - 1, true);
}
});
getFragment(0, false);
}
private void setupViewPager() {
bottomLayout = findViewById(R.id.linearLayout);
private void getFragment(int position, boolean animate) {
pagerAdapter = new SimplePagerAdapter(getSupportFragmentManager());
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
viewPager = findViewById(R.id.viewPager);
viewPager.setPagingEnabled(false);
viewPager.setAdapter(pagerAdapter);
if (animate) {
if (position > currentFragmentPosition) {
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
} else {
transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
}
}
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
currentFragmentPosition = position;
switch (position) {
case 0:
prevButton.setEnabled(false);
nextButton.setEnabled(false);
transaction.replace(R.id.fragmentContainer, new SyncStartFragment());
break;
case 1:
prevButton.setEnabled(true);
if (partnerChoice == 1) {
nextButton.setEnabled(false);
transaction.replace(R.id.fragmentContainer, new ScanQrFragment(), "FRAGMENT_SCAN");
@Override
public void onPageSelected(int position) {
if (position == 0) {
bottomLayout.setVisibility(View.GONE);
} else {
bottomLayout.setVisibility(View.VISIBLE);
nextButton.setEnabled(true);
transaction.replace(R.id.fragmentContainer, new ShowQrFragment(), "FRAGMENT_SHOW");
}
}
break;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
case 2:
if (partnerChoice == 1) {
}
prevButton.setEnabled(true);
nextButton.setEnabled(true);
transaction.replace(R.id.fragmentContainer, new ShowQrFragment(), "FRAGMENT_SHOW");
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
@Override
public void onPageScrollStateChanged(int state) {
} else {
}
});
prevButton.setEnabled(true);
nextButton.setEnabled(false);
Button next = findViewById(R.id.nextButton);
Button back = findViewById(R.id.backButton);
transaction.replace(R.id.fragmentContainer, new ScanQrFragment(), "FRAGMENT_SCAN");
}
break;
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
}
});
case 3:
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1, true);
}
});
nextButton.setText("Finish");
nextButton.setEnabled(false);
transaction.replace(R.id.fragmentContainer, new UploadFragment());
break;
default:
break;
}
transaction.commit();
}
private class SimplePagerAdapter extends FragmentStatePagerAdapter {
public void setPartnerChoice(int choice) {
public SimplePagerAdapter(FragmentManager fm) {
super(fm);
}
partnerChoice = choice;
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new SyncStartFragment(); // start fragment
case 1:
return new ScanQrFragment(); // scan fragment
case 2:
return new ShowQrFragment(); // show QR fragment
case 3:
return new UploadFragment(); // show upload fragment
default:
return null; // This should not be happening
}
}
@Override
public int getCount() {
return PAGE_COUNT;
if (choice != -1) {
nextButton.setEnabled(true);
} else {
nextButton.setEnabled(false);
}
}
private void uploadOrganisation(Organisation org) {
MispRequest mispRequest = MispRequest.Instance(this);
public void setScannedQr(String qr) {
mispRequest.getOrganisations(new MispRequest.OrganisationsCallback() {
@Override
public void onResult(JSONArray organisations) {
final FragmentManager manager = getSupportFragmentManager();
final ScanQrFragment scanFragment = (ScanQrFragment) manager.findFragmentByTag("FRAGMENT_SCAN");
}
scanFragment.setReadQr(false);
try {
OrganisationDialog d = new OrganisationDialog(this);
Organisation o = new Organisation();
o.fromJSON(new JSONObject(qr));
d.createDialog(o);
@Override
public void onError(VolleyError volleyError) {
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
public void uploadReady() {
nextButton.setEnabled(true);
}
}

View File

@ -27,6 +27,9 @@ public class OrganisationDialog {
TextView title = dialogContent.findViewById(R.id.organisation_title);
title.setText(org.getName());
TextView uuid = dialogContent.findViewById(R.id.organisation_uuid);
uuid.setText(org.getUuid());
TextView description = dialogContent.findViewById(R.id.organisation_description);
description.setText(org.getDescription());
@ -39,7 +42,9 @@ public class OrganisationDialog {
TextView userCount = dialogContent.findViewById(R.id.organisation_user_count);
userCount.setText("" + org.getUserCount());
// dialogBuilder.setPositiveButton("OK", null);
dialogBuilder.setCancelable(false);
dialogBuilder.setNegativeButton("REJECT", null);
dialogBuilder.setPositiveButton("ACCEPT", null);
dialogBuilder.show();
}
}

View File

@ -1,17 +1,361 @@
package de.overview.wg.its.mispauth.fragment;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.*;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.renderscript.*;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.content.ContextCompat;
import android.util.Size;
import android.util.SparseArray;
import android.view.*;
import android.widget.Toast;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.activity.SyncActivity;
import java.util.Arrays;
import java.util.List;
public class ScanQrFragment extends Fragment {
private static final int CAMERA_REQUEST_CODE = 0;
private HandlerThread backgroundThread;
private Handler backgroundHandler;
private CameraManager cameraManager;
private CameraDevice cameraDevice;
private String cameraID;
private CameraCaptureSession cameraCaptureSession;
private SurfaceTexture previewSurfaceTexture;
private Surface previewSurface, yuvSurface;
private Size[] yuvSizes;
private BarcodeDetector barcodeDetector;
private TextureView previewView;
private boolean readQr = true;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sync_scan, null);
previewView = v.findViewById(R.id.texture_scan_preview);
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
}
} else {
setUpBarcodeDetector();
setUpPreviewTexture();
}
return v;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case CAMERA_REQUEST_CODE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setUpBarcodeDetector();
setUpPreviewTexture();
} else {
Toast.makeText(getActivity(), "Camera permission needed!", Toast.LENGTH_SHORT).show();
}
}
}
}
@Override
public void onResume() {
super.onResume();
openBackgroundThread();
}
@Override
public void onStop() {
super.onStop();
closeCamera();
closeBackgroundThread();
}
private void returnResult(String qrData) {
((SyncActivity) getActivity()).setScannedQr(qrData);
}
private void setUpPreviewTexture() {
previewView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
surface.setDefaultBufferSize(width, height);
previewSurfaceTexture = surface;
setUpCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
}
private void setUpCamera() {
cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
if (facing == CameraCharacteristics.LENS_FACING_BACK) {
cameraID = cameraId;
StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
yuvSizes = streamConfigurationMap.getOutputSizes(ImageFormat.YUV_420_888);
setUpImageReader();
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void setUpImageReader() {
Size yuvSize = yuvSizes[yuvSizes.length - 6];
ImageReader yuvImageReader = ImageReader.newInstance(yuvSize.getWidth(), yuvSize.getHeight(), ImageFormat.YUV_420_888, 5);
ImageReader.OnImageAvailableListener yuvImageListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
if (!readQr) {
return;
}
Image lastImage = reader.acquireLatestImage();
Bitmap bitmap = YUV2Bitmap(lastImage);
if (bitmap != null) {
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
SparseArray<Barcode> barcodes = barcodeDetector.detect(frame);
if (barcodes.size() > 0) {
returnResult(barcodes.valueAt(0).rawValue);
}
}
if (lastImage != null) {
lastImage.close();
}
}
};
yuvImageReader.setOnImageAvailableListener(yuvImageListener, backgroundHandler);
previewSurface = new Surface(previewSurfaceTexture);
yuvSurface = yuvImageReader.getSurface();
openCamera();
}
public void openCamera() {
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
cameraDevice = camera;
createCaptureSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
}
};
try {
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraManager.openCamera(cameraID, stateCallback, backgroundHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCaptureSession() {
List<Surface> surfaces = Arrays.asList(previewSurface, yuvSurface);
CameraCaptureSession.StateCallback captureStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
cameraCaptureSession = session;
createCaptureRequest();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
};
try {
cameraDevice.createCaptureSession(surfaces, captureStateCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCaptureRequest() {
try {
CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
requestBuilder.addTarget(previewSurface);
requestBuilder.addTarget(yuvSurface);
CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
}
};
cameraCaptureSession.setRepeatingRequest(requestBuilder.build(), captureCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openBackgroundThread() {
backgroundThread = new HandlerThread("raw_image_available_listener_thread");
backgroundThread.start();
backgroundHandler = new Handler(backgroundThread.getLooper());
}
private void closeBackgroundThread() {
backgroundThread.quitSafely();
try {
backgroundThread.join();
backgroundThread = null;
backgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void closeCamera() {
if (cameraCaptureSession != null) {
cameraCaptureSession.close();
cameraCaptureSession = null;
}
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
}
private void setUpBarcodeDetector() {
barcodeDetector = new BarcodeDetector.Builder(getActivity())
.setBarcodeFormats(Barcode.QR_CODE)
.build();
if (!barcodeDetector.isOperational()) {
Toast.makeText(getActivity(), "Could not setup QR-Code scanner!", Toast.LENGTH_SHORT).show();
}
}
private Bitmap YUV2Bitmap(Image image) {
if (image == null) return null;
int W = image.getWidth();
int H = image.getHeight();
Image.Plane Y = image.getPlanes()[0];
Image.Plane U = image.getPlanes()[1];
Image.Plane V = image.getPlanes()[2];
int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();
byte[] data = new byte[Yb + Ub + Vb];
Y.getBuffer().get(data, 0, Yb);
V.getBuffer().get(data, Yb, Vb);
U.getBuffer().get(data, Yb + Vb, Ub);
RenderScript rs = RenderScript.create(getActivity().getApplicationContext());
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
in.copyFromUnchecked(data);
yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);
out.copyTo(bmpout);
image.close();
return bmpout;
}
public void setReadQr(boolean enabled) {
readQr = enabled;
}
}

View File

@ -1,27 +1,52 @@
package de.overview.wg.its.mispauth.fragment;
import android.graphics.Point;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
import net.glxn.qrgen.android.QRCode;
public class ShowQrFragment extends Fragment {
private ImageView qrImageView;
private int screenWidth, screenHeight;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sync_show, null);
// DisplayMetrics metrics = new DisplayMetrics();
// getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
//
// screenWidth = (int)(metrics.widthPixels * metrics.density);
// screenHeight = (int)(metrics.heightPixels * metrics.density);
// Display display = getActivity().getWindowManager().getDefaultDisplay();
// Point size = new Point();
// display.getSize(size);
// screenWidth = size.x;
// screenHeight = size.y;
screenHeight = getResources().getDisplayMetrics().heightPixels;
screenWidth = getResources().getDisplayMetrics().widthPixels;
qrImageView = v.findViewById(R.id.image_view_qr);
setQr("Hallo hier steht leide nur scheiße, aber ansonsten hat alles geklappt! (Y)");
PreferenceManager preferenceManager = PreferenceManager.Instance(getActivity());
setQr(preferenceManager.getMyOrganisation().toJSON().toString());
return v;
}
public void setQr(String msg) {
qrImageView.setImageBitmap(QRCode.from(msg).bitmap());
private void setQr(String msg) {
qrImageView.setImageBitmap(QRCode.from(msg)
.withSize(screenHeight, screenHeight)
.bitmap());
}
}

View File

@ -1,17 +1,33 @@
package de.overview.wg.its.mispauth.fragment;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioGroup;
import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.activity.SyncActivity;
public class SyncStartFragment extends Fragment {
private static final String TAG = "DEBUG";
private RadioGroup radioGroup;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sync_start, null);
radioGroup = v.findViewById(R.id.radioGroup);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
((SyncActivity)getActivity()).setPartnerChoice(checkedId % 2);
}
});
return v;
}
}

View File

@ -0,0 +1,5 @@
package de.overview.wg.its.mispauth.interfaces;
public interface IProcessable {
boolean isDone();
}

View File

@ -0,0 +1,6 @@
package de.overview.wg.its.mispauth.interfaces;
public interface ISyncCommunication {
void setPartnerChoice(int choice);
void setScannedQr(String qr);
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300" />
</set>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="150"/>
</set>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="150" />
</set>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad"
android:valueFrom="0"
android:valueTo="1"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime"/>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="2dp"
android:useLevel="false">
<solid android:color="@android:color/darker_gray"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:useLevel="false" >
<solid android:color="@color/colorAccent"/>
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/tab_indicator_selected"
android:state_selected="true"/>
<item android:drawable="@drawable/tab_indicator_default"/>
</selector>

View File

@ -12,6 +12,7 @@
android:background="@color/colorPrimary">
<android.support.design.widget.AppBarLayout
app:elevation="0dp"
android:id="@+id/sync.appbar"
android:background="@color/colorPrimaryDark"
android:layout_width="match_parent"
@ -35,19 +36,24 @@
android:padding="0dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<de.overview.wg.its.mispauth.custom_viewpager.ExtendedViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
<FrameLayout
android:id="@+id/fragmentContainer"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"/>
app:layout_constraintTop_toTopOf="parent"
android:layout_width="0dp"
android:layout_height="0dp">
</FrameLayout>
<LinearLayout
android:id="@+id/linearLayout"
android:background="@color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="56dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
@ -57,18 +63,26 @@
android:id="@+id/backButton"
android:text="Back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="match_parent"
android:enabled="false"/>
<TextView
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
android:layout_height="match_parent"
app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp">
</android.support.design.widget.TabLayout>
<Button style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:id="@+id/nextButton"
android:text="Next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="match_parent"
android:enabled="false"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>

View File

@ -1,17 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scan QR"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="8dp"
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp"/>
<TextureView
android:id="@+id/texture_scan_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>

View File

@ -1,12 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_view_qr"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_width="wrap_content"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

View File

@ -5,32 +5,69 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/sync_image"
android:src="@drawable/ic_sync_alpha"
<RadioGroup
android:id="@+id/radioGroup"
android:padding="16dp"
android:layout_width="match_parent"
android:layout_height="128dp"/>
android:layout_height="wrap_content" android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp" android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:gravity="center"
android:id="@+id/help_text_sync"
android:text="I am partner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/sync_image"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:textSize="20sp"
android:textStyle="bold"
android:text="How would you like to start?"/>
<Button style="@style/CustomButton"
android:id="@+id/button_scan"
android:text="Scan"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/button_share"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:textSize="17sp"
android:text="Make sure your partner will choose the opposite option."/>
<Button style="@style/CustomButton"
android:id="@+id/button_share"
android:text="Share"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"/>
<RadioButton
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Scan QR-Code first"/>
<RadioButton
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Share QR-Code first"/>
</RadioGroup>
<!--<ImageView-->
<!--android:id="@+id/sync_image"-->
<!--android:src="@drawable/ic_sync_alpha"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="128dp"/>-->
<!--<TextView-->
<!--android:gravity="center"-->
<!--android:id="@+id/help_text_sync"-->
<!--android:text="I am partner"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--app:layout_constraintTop_toBottomOf="@+id/sync_image"/>-->
<!--<Button style="@style/CustomButton"-->
<!--android:id="@+id/button_scan"-->
<!--android:text="Scan"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content" android:layout_marginBottom="8dp"-->
<!--app:layout_constraintBottom_toTopOf="@+id/button_share"/>-->
<!--<Button style="@style/CustomButton"-->
<!--android:id="@+id/button_share"-->
<!--android:text="Share"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content" android:layout_marginBottom="8dp"-->
<!--app:layout_constraintBottom_toBottomOf="parent"/>-->
</android.support.constraint.ConstraintLayout>