please help guys,, here is my code for my simple gallery android app for external images
I made the loader is in array , and I made swiping action ,,
what I think I have to chose Wither removechild nor enter frame but I can't apply it
coz when publish, things is mixed up and swiping is not working well :(
could you please help me to fix it it's AS3 at Flash 5.5
var pictureArray:Array = new Array;
var loader1 = new Loader();
loader1.load(new URLRequest("1.jpg"));
pictureArray.push(loader1);
var loader2 = new Loader();
loader2.load(new URLRequest("2.jpg"));
pictureArray.push(loader2);
var loader3 = new Loader();
loader3.load(new URLRequest("3.jpg"));
pictureArray.push(loader3);
addChild(pictureArray[0]);
pictureArray[0].x = 0; pictureArray[0].y = 0;
var n:int = 0;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
var currentGalleryItem:Number = 1;
var totalGalleryItems:Number = 3;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrame);
function fl_SwipeToGoToNextPreviousFrame(event:TransformGestureEvent):void
{
if(event.offsetX == 1)
{
if(currentGalleryItem > 1){
currentGalleryItem--;
slideRight();
removeChild(pictureArray[n]);
n = n+1;
if (n>pictureArray.length - 1)
n=0;
addChild(pictureArray[n]);
pictureArray[n].x = 0; pictureArray[n].y = 0;
}
}
else if(event.offsetX == -1)
{
if(currentGalleryItem < totalGalleryItems){
currentGalleryItem++;
slideLeft();
removeChild(pictureArray[n]);
n = n-1;
if (n<0)
n=pictureArray.length - 1;
addChild(pictureArray[n]);
pictureArray[n].x = 0; pictureArray[n].y = 0;
}
}
}
var slideCounter:Number = 0;
function slideLeft(){
(pictureArray[n]).addEventListener("enterFrame", moveGalleryLeft);
}
function slideRight(){
(pictureArray[n]).addEventListener("enterFrame", moveGalleryRight);
}
function moveGalleryLeft(evt:Event){
(pictureArray[n]).x -= 48;
slideCounter++;
if(slideCounter == 5){
(pictureArray[n]).removeEventListener("enterFrame", moveGalleryLeft);
slideCounter = 0;
}
}
function moveGalleryRight(evt:Event){
(pictureArray[n]).x += 48;
slideCounter++;
if(slideCounter == 5){
(pictureArray[n]).removeEventListener("enterFrame", moveGalleryRight);
slideCounter = 0;
}
}
I would recommend load images on demand, for animation use some tweening engine(in my example It's TweenLite), and dispose previous frames, It's mobile device you should honour memory. Most of other comments in the code, I don't have ability to test in on the device, also It's not complete code, It's only carcass ;)
package {
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.TransformGestureEvent;
import flash.net.URLRequest;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class StackOverflow extends Sprite {
private var _loader:Loader;
private var _images:Array;
private var _position:int;
private var _currentFrame:Sprite;
public function StackOverflow() {
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function setup():void {
_loader = new Loader();
_images = ["1.jpg", "2.jpg", "3.jpg"];
_currentFrame = new Sprite();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImage);
stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE, onSwipe);
addChild(_currentFrame);
loadImageAtPosition(_position);
}
private function disposeFrame(frame:Sprite):void {
//You can cache loaded bitmaps, or dispose them
removeChild(frame);
var bitmap:Bitmap = frame.getChildAt(0) as Bitmap;
bitmap.bitmapData.dispose();
}
private function loadImageAtPosition(index:int):void {
//By using one loader for all tasks, you will have only last requested image
_loader.load(new URLRequest(_images[index]));
}
private function offsetScreenOn(direction:Number):void {
var offset:int;
var start:int;
if (direction > 0) {
//Direction to the right side
offset = stage.stageWidth;
} else {
//Direction to the left side
offset = -stage.stageWidth;
}
//Starting position for new frame
start = -offset;
//TweenLite is great for such task
if (_currentFrame != null) {
//Remove previous frame
TweenLite.to(_currentFrame, 0.8, {x: offset, onComplete: disposeFrame, onCompleteParams: [_currentFrame]});
}
//Initialise new frame, fill them, decor them...
_currentFrame = new Sprite();
if (_currentFrame != null) {
addChild(_currentFrame);
_currentFrame.x = start;
//Animate in new frame
TweenLite.to(_currentFrame, 0.8, {x: (start + offset)});
}
}
private function onLoadImage(e:Event):void {
if (_currentFrame != null) {
var image:Bitmap = _loader.content as Bitmap;
if (image != null) {
image.smoothing = true;
_currentFrame.addChild(image);
//Resize, displace image for your needs
//Add appear animation if you want
}
}
}
//If you want, you can postpone swipe, while in state of transition
private function onSwipe(e:TransformGestureEvent):void {
//Left to Right swipe
if (e.offsetX == 1) {
if (--_position < 0) {
_position = _images.length;
}
offsetScreenOn(e.offsetX);
loadImageAtPosition(_position);
}
//Right to Left swipe
if (e.offsetX == -1) {
if (++_position >= _images.length) {
_position = 0;
}
offsetScreenOn(e.offsetX);
loadImageAtPosition(_position);
}
}
private function onAdded(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, onAdded);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
setup();
}
}
}
check this out
simple android gallery
it a basic implementation of a gallery app, it makes use of the android media provider to actually get images in the device storage and provides an image slider by using a viewPager and a RecyclerView as indicator, I will outline the important parts here, you can use a RecyclerView and a Recycler Adapter to display your images
public class picture_Adapter extends RecyclerView.Adapter<PicHolder> {
private ArrayList<pictureFacer> pictureList;
private Context pictureContx;
private final itemClickListener picListerner;
/**
*
* #param pictureList ArrayList of pictureFacer objects
* #param pictureContx The Activities Context
* #param picListerner An interface for listening to clicks on the RecyclerView's items
*/
public picture_Adapter(ArrayList<pictureFacer> pictureList, Context pictureContx,itemClickListener picListerner) {
this.pictureList = pictureList;
this.pictureContx = pictureContx;
this.picListerner = picListerner;
}
#NonNull
#Override
public PicHolder onCreateViewHolder(#NonNull ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(container.getContext());
View cell = inflater.inflate(R.layout.pic_holder_item, container, false);
return new PicHolder(cell);
}
#Override
public void onBindViewHolder(#NonNull final PicHolder holder, final int position) {
final pictureFacer image = pictureList.get(position);
Glide.with(pictureContx)
.load(image.getPicturePath())
.apply(new RequestOptions().centerCrop())
.into(holder.picture);
setTransitionName(holder.picture, String.valueOf(position) + "_image");
holder.picture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
picListerner.onPicClicked(holder,position, pictureList);
}
});
}
#Override
public int getItemCount() {
return pictureList.size();
}
}
the method below gets all the device images and load the info for each image in a imageFacer object which you can use to populate the recyclerview adapter
see the full post in the link above
public ArrayList<pictureFacer> getAllImagesByFolder(String path){
ArrayList<pictureFacer> images = new ArrayList<>();
Uri allVideosuri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Images.ImageColumns.DATA ,MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.SIZE};
Cursor cursor = ImageDisplay.this.getContentResolver().query( allVideosuri, projection, MediaStore.Images.Media.DATA + " like ? ", new String[] {"%"+path+"%"}, null);
try {
cursor.moveToFirst();
do{
pictureFacer pic = new pictureFacer();
pic.setPicturName(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)));
pic.setPicturePath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)));
pic.setPictureSize(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE)));
images.add(pic);
}while(cursor.moveToNext());
cursor.close();
ArrayList<pictureFacer> reSelection = new ArrayList<>();
for(int i = images.size()-1;i > -1;i--){
reSelection.add(images.get(i));
}
images = reSelection;
} catch (Exception e) {
e.printStackTrace();
}
return images;
}
Related
I have ExoPlayer which plays HLS videos, the thing is i need to give user ability to change video quality(auto/1080/720/480).
I figured out that playing around with AdaptiveTrackSelection.Factory does set the quality, but it remains till the object is killed.
I have also tried using MappingTrackSelector, i know that my video has 4 tracks, but i did not get how to select any of it manually. Will this selection make it work?
Thanks for any ideas.
MappingTrackSelector.MappedTrackInfo trackInfo = mDefaultTrackSelector.getCurrentMappedTrackInfo();
mDefaultTrackSelector.selectTracks(
//what should go here?
, trackInfo.getTrackGroups(4));
Regarding this thread :https://github.com/google/ExoPlayer/issues/2250, I managed to change exo player video quality while playing previous one, so it does not getting in buffering instantly.
So I have next classes :
public enum HLSQuality {
Auto, Quality1080, Quality720, Quality480, NoValue
}
class HLSUtil {
private HLSUtil() {
}
#NonNull
static HLSQuality getQuality(#NonNull Format format) {
switch (format.height) {
case 1080: {
return HLSQuality.Quality1080;
}
case 720: {
return HLSQuality.Quality720;
}
case 480:
case 486: {
return HLSQuality.Quality480;
}
default: {
return HLSQuality.NoValue;
}
}
}
static boolean isQualityPlayable(#NonNull Format format) {
return format.height <= 1080;
}
}
public class ClassAdaptiveTrackSelection extends BaseTrackSelection {
public static final class Factory implements TrackSelection.Factory {
private final BandwidthMeter bandwidthMeter;
private final int maxInitialBitrate = 2000000;
private final int minDurationForQualityIncreaseMs = 10000;
private final int maxDurationForQualityDecreaseMs = 25000;
private final int minDurationToRetainAfterDiscardMs = 25000;
private final float bandwidthFraction = 0.75f;
private final float bufferedFractionToLiveEdgeForQualityIncrease = 0.75f;
public Factory(BandwidthMeter bandwidthMeter) {
this.bandwidthMeter = bandwidthMeter;
}
#Override
public ClassAdaptiveTrackSelection createTrackSelection(TrackGroup group, int... tracks) {
Log.d(ClassAdaptiveTrackSelection.class.getSimpleName(), " Video player quality reset to Auto");
sHLSQuality = HLSQuality.Auto;
return new ClassAdaptiveTrackSelection(
group,
tracks,
bandwidthMeter,
maxInitialBitrate,
minDurationForQualityIncreaseMs,
maxDurationForQualityDecreaseMs,
minDurationToRetainAfterDiscardMs,
bandwidthFraction,
bufferedFractionToLiveEdgeForQualityIncrease
);
}
}
private static HLSQuality sHLSQuality = HLSQuality.Auto;
private final BandwidthMeter bandwidthMeter;
private final int maxInitialBitrate;
private final long minDurationForQualityIncreaseUs;
private final long maxDurationForQualityDecreaseUs;
private final long minDurationToRetainAfterDiscardUs;
private final float bandwidthFraction;
private final float bufferedFractionToLiveEdgeForQualityIncrease;
private int selectedIndex;
private int reason;
private ClassAdaptiveTrackSelection(TrackGroup group,
int[] tracks,
BandwidthMeter bandwidthMeter,
int maxInitialBitrate,
long minDurationForQualityIncreaseMs,
long maxDurationForQualityDecreaseMs,
long minDurationToRetainAfterDiscardMs,
float bandwidthFraction,
float bufferedFractionToLiveEdgeForQualityIncrease) {
super(group, tracks);
this.bandwidthMeter = bandwidthMeter;
this.maxInitialBitrate = maxInitialBitrate;
this.minDurationForQualityIncreaseUs = minDurationForQualityIncreaseMs * 1000L;
this.maxDurationForQualityDecreaseUs = maxDurationForQualityDecreaseMs * 1000L;
this.minDurationToRetainAfterDiscardUs = minDurationToRetainAfterDiscardMs * 1000L;
this.bandwidthFraction = bandwidthFraction;
this.bufferedFractionToLiveEdgeForQualityIncrease = bufferedFractionToLiveEdgeForQualityIncrease;
selectedIndex = determineIdealSelectedIndex(Long.MIN_VALUE);
reason = C.SELECTION_REASON_INITIAL;
}
#Override
public void updateSelectedTrack(long playbackPositionUs, long bufferedDurationUs, long availableDurationUs) {
long nowMs = SystemClock.elapsedRealtime();
// Stash the current selection, then make a new one.
int currentSelectedIndex = selectedIndex;
selectedIndex = determineIdealSelectedIndex(nowMs);
if (selectedIndex == currentSelectedIndex) {
return;
}
if (!isBlacklisted(currentSelectedIndex, nowMs)) {
// Revert back to the current selection if conditions are not suitable for switching.
Format currentFormat = getFormat(currentSelectedIndex);
Format selectedFormat = getFormat(selectedIndex);
if (selectedFormat.bitrate > currentFormat.bitrate
&& bufferedDurationUs < minDurationForQualityIncreaseUs(availableDurationUs)) {
// The selected track is a higher quality, but we have insufficient buffer to safely switch
// up. Defer switching up for now.
selectedIndex = currentSelectedIndex;
} else if (selectedFormat.bitrate < currentFormat.bitrate
&& bufferedDurationUs >= maxDurationForQualityDecreaseUs) {
// The selected track is a lower quality, but we have sufficient buffer to defer switching
// down for now.
selectedIndex = currentSelectedIndex;
}
}
// If we adapted, update the trigger.
if (selectedIndex != currentSelectedIndex) {
reason = C.SELECTION_REASON_ADAPTIVE;
}
}
#Override
public int getSelectedIndex() {
return selectedIndex;
}
#Override
public int getSelectionReason() {
return reason;
}
#Override
public Object getSelectionData() {
return null;
}
#Override
public int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue) {
if (queue.isEmpty()) {
return 0;
}
int queueSize = queue.size();
long bufferedDurationUs = queue.get(queueSize - 1).endTimeUs - playbackPositionUs;
if (bufferedDurationUs < minDurationToRetainAfterDiscardUs) {
return queueSize;
}
int idealSelectedIndex = determineIdealSelectedIndex(SystemClock.elapsedRealtime());
Format idealFormat = getFormat(idealSelectedIndex);
// If the chunks contain video, discard from the first SD chunk beyond
// minDurationToRetainAfterDiscardUs whose resolution and bitrate are both lower than the ideal
// track.
for (int i = 0; i < queueSize; i++) {
MediaChunk chunk = queue.get(i);
Format format = chunk.trackFormat;
long durationBeforeThisChunkUs = chunk.startTimeUs - playbackPositionUs;
if (durationBeforeThisChunkUs >= minDurationToRetainAfterDiscardUs
&& format.bitrate < idealFormat.bitrate
&& format.height != Format.NO_VALUE && format.height < 720
&& format.width != Format.NO_VALUE && format.width < 1280
&& format.height < idealFormat.height) {
return i;
}
}
return queueSize;
}
private int determineIdealSelectedIndex(long nowMs) {
if (sHLSQuality != HLSQuality.Auto) {
Log.d(ClassAdaptiveTrackSelection.class.getSimpleName(), " Video player quality seeking for " + String.valueOf(sHLSQuality));
for (int i = 0; i < length; i++) {
Format format = getFormat(i);
if (HLSUtil.getQuality(format) == sHLSQuality) {
Log.d(ClassAdaptiveTrackSelection.class.getSimpleName(), " Video player quality set to " + String.valueOf(sHLSQuality));
return i;
}
}
}
Log.d(ClassAdaptiveTrackSelection.class.getSimpleName(), " Video player quality seeking for auto quality " + String.valueOf(sHLSQuality));
long bitrateEstimate = bandwidthMeter.getBitrateEstimate();
long effectiveBitrate = bitrateEstimate == BandwidthMeter.NO_ESTIMATE
? maxInitialBitrate : (long) (bitrateEstimate * bandwidthFraction);
int lowestBitrateNonBlacklistedIndex = 0;
for (int i = 0; i < length; i++) {
if (nowMs == Long.MIN_VALUE || !isBlacklisted(i, nowMs)) {
Format format = getFormat(i);
if (format.bitrate <= effectiveBitrate && HLSUtil.isQualityPlayable(format)) {
Log.d(ClassAdaptiveTrackSelection.class.getSimpleName(), " Video player quality auto quality found " + String.valueOf(sHLSQuality));
return i;
} else {
lowestBitrateNonBlacklistedIndex = i;
}
}
}
return lowestBitrateNonBlacklistedIndex;
}
private long minDurationForQualityIncreaseUs(long availableDurationUs) {
boolean isAvailableDurationTooShort = availableDurationUs != C.TIME_UNSET
&& availableDurationUs <= minDurationForQualityIncreaseUs;
return isAvailableDurationTooShort
? (long) (availableDurationUs * bufferedFractionToLiveEdgeForQualityIncrease)
: minDurationForQualityIncreaseUs;
}
static void setHLSQuality(HLSQuality HLSQuality) {
sHLSQuality = HLSQuality;
}
}
Hope it helps someone.
You can check out ExoPlayer_TrackSelection from github for changing video quality manually.
Hi I want to open a activity when a if statement comes true. like "if gameStatus are equal to 12, then open scoreActivity". The Code:
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.GridLayout;
import java.util.Random;
import android.os.Build;
import android.os.Handler;
public class Game6x4Activity extends AppCompatActivity implements View.OnClickListener {
private int numberOfElements;
private int[] buttonGraphicLocations;
private MemoryButton selectedButton1;
private MemoryButton selectedButton2;
private boolean isBusy = false;
public int gameStatus;
public int gameScore;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_mode);
gameScore = 0;
gameStatus = 0;
GridLayout gridLayout = (GridLayout)findViewById(R.id.grid_layout_6x4);
int numColumns = gridLayout.getColumnCount();
int numRow = gridLayout.getRowCount();
numberOfElements = numColumns * numRow;
MemoryButton[] buttons = new MemoryButton[numberOfElements];
int[] buttonGraphics = new int[numberOfElements / 2];
buttonGraphics[0] = R.drawable.card1;
buttonGraphics[1] = R.drawable.card2;
buttonGraphics[2] = R.drawable.card3;
buttonGraphics[3] = R.drawable.card4;
buttonGraphics[4] = R.drawable.card5;
buttonGraphics[5] = R.drawable.card6;
buttonGraphics[6] = R.drawable.card7;
buttonGraphics[7] = R.drawable.card8;
buttonGraphics[8] = R.drawable.card9;
buttonGraphics[9] = R.drawable.card10;
buttonGraphics[10] = R.drawable.card11;
buttonGraphics[11] = R.drawable.card12;
buttonGraphicLocations = new int[numberOfElements];
shuffleButtonGraphics();
for(int r=0; r < numRow; r++)
{
for(int c=0; c <numColumns; c++)
{
MemoryButton tempButton = new MemoryButton(this, r, c, buttonGraphics[buttonGraphicLocations[r * numColumns + c]]);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
tempButton.setId(View.generateViewId());
}
tempButton.setOnClickListener(this);
buttons[r * numColumns + c] = tempButton;
gridLayout.addView(tempButton);
}
}
}
protected void shuffleButtonGraphics(){
Random rand = new Random();
for (int i=0; i < numberOfElements; i++)
{
buttonGraphicLocations[i] = i % (numberOfElements / 2);
}
for (int i=0; i < numberOfElements; i++)
{
int temp = buttonGraphicLocations[i];
int swapIndex = rand.nextInt(16);
buttonGraphicLocations[i] = buttonGraphicLocations[swapIndex];
buttonGraphicLocations[swapIndex] = temp;
}
}
private int buttonGraphicLocations(int i) {
return 0;
}
#Override
public void onClick(View view) {
if(isBusy) {
return;
}
MemoryButton button = (MemoryButton) view;
if(button.isMatched) {
return;
}
if(selectedButton1 == null)
{
selectedButton1 = button;
selectedButton1.flip();
return;
}
if(selectedButton1.getId()== button.getId())
{
return;
}
if (selectedButton1.getFrontDrawableId()== button.getFrontDrawableId())
{
button.flip();
button.setMatched(true);
if (selectedButton1 != null) {
selectedButton1.setEnabled(false);
System.out.println("not null");
}
else{
System.out.println("null");
}
if (selectedButton2 != null) {
selectedButton2.setEnabled(false);
System.out.println("not null");
}
else{
System.out.println("null");
}
gameStatus = gameStatus + 1;
gameScore = gameScore + 10;
if (gameStatus == 12){
Intent it = new Intent(Game6x4Activity.this, ActivityScore.class);
startActivity(it);
}
selectedButton1 = null;
return;
}
else
{
selectedButton2 = button;
selectedButton2.flip();
isBusy = true;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run(){
selectedButton2.flip();
selectedButton1.flip();
selectedButton1 = null;
selectedButton2 = null;
isBusy = false;
}
},500);
return;
}
}
}
The activity that i want to open will show to the player his score. the activity is equal to all game modes, there will be some test to the app understant what path should go on. test like this one:
"
if (gameStatus == 12) {
gameScore = gameScore*55;
TextView scoreText = (TextView) findViewById(R.id.textView8);
scoreText.setText(gameScore);
}
else if (gameStatus == 15){
"
There are 4 game modes: This is the 6x4 game, where we can find 24 cards (12 images).
else if (gameStatus == 15){
Intent intent = new Intent(Game6x4Activity.this, NextActivity.class);
startActivity(intent);
}
I think, you are asking for this. You can pass value to another activity with
intent.putExtra("key",desired value);
I'd like to use ExoPlayer2 with playlists having possibility to dinamically change the tracks (add or remove them from playlist) and change the loop settings.
Since ConcatenatingMediaSource has static arrays (and not lists), I'm implementing a DynamicMediaSource, like Concatenating one but with lists instead of arrays and one mode method addSource to add one more media source to the list.
public void addSource(MediaSource mediaSource) {
this.mediaSources.add(mediaSource);
duplicateFlags = buildDuplicateFlags(this.mediaSources);
if(!mediaSources.isEmpty())
prepareSource(mediaSources.size() -1);
else
prepareSource(0);
}
When I invoke addSource
MediaSource ms = buildMediaSource(mynewuri, null);
mediaSource.addSource(ms);
the track is added to the arrays but it seems something is missing because I always obtain ArrayOutOfBoundsException in createPeriod method.
In createPeriod the method
mediaSources.get(sourceIndex)...
is trying to access the index = mediaSources.size().
Can you help me?
I eventually managed it.
It was my fault during the conversion from arrays to lists.
I had to use SparseArrays for timelines and manifests and everything began to work.
In the DynamicMediaSource simply set the following types:
private final List<MediaSource> mediaSources;
private final SparseArray<Timeline> timelines;
private final SparseArray<Object> manifests;
private final Map<MediaPeriod, Integer> sourceIndexByMediaPeriod;
private SparseArray<Boolean> duplicateFlags;
you have to use sparse arrays to set the proper values into the timelines and manifests in the method
private void handleSourceInfoRefreshed(int sourceFirstIndex, Timeline sourceTimeline,
Object sourceManifest) {
// Set the timeline and manifest.
timelines.put(sourceFirstIndex, sourceTimeline);
manifests.put(sourceFirstIndex, sourceManifest);
// Also set the timeline and manifest for any duplicate entries of the same source.
for (int i = sourceFirstIndex + 1; i < mediaSources.size(); i++) {
if (mediaSources.get(i).equals(mediaSources.get(sourceFirstIndex))) {
timelines.put(i, sourceTimeline);
manifests.put(i, sourceManifest);
}
}
for(int i= 0; i<mediaSources.size(); i++){
if(timelines.get(i) == null){
// Don't invoke the listener until all sources have timelines.
return;
}
}
timeline = new DynamicTimeline(new ArrayList(asList(timelines)));
listener.onSourceInfoRefreshed(timeline, new ArrayList(asList(manifests)));
}
Here is the complete code of DynamicMediaSource class:
public final class DynamicMediaSource implements MediaSource {
private static final String TAG = "DynamicSource";
private final List<MediaSource> mediaSources;
private final List<Timeline> timelines;
private final List<Object> manifests;
private final Map<MediaPeriod, Integer> sourceIndexByMediaPeriod;
private SparseArray<Boolean> duplicateFlags;
private Listener listener;
private DynamicTimeline timeline;
/**
* #param mediaSources The {#link MediaSource}s to concatenate. It is valid for the same
* {#link MediaSource} instance to be present more than once in the array.
*/
public DynamicMediaSource(MediaSource... mediaSources) {
this.mediaSources = new ArrayList<MediaSource>(Arrays.asList(mediaSources));
timelines = new ArrayList<Timeline>();
manifests = new ArrayList<Object>();
sourceIndexByMediaPeriod = new HashMap<>();
duplicateFlags = buildDuplicateFlags(this.mediaSources);
}
public void addSource(MediaSource mediaSource) {
this.mediaSources.add(mediaSource);
duplicateFlags = buildDuplicateFlags(this.mediaSources);
/*if(!mediaSources.isEmpty())
prepareSource(mediaSources.size() -1);
else
prepareSource(0);*/
}
#Override
public void prepareSource(Listener listener) {
this.listener = listener;
for (int i = 0; i < mediaSources.size(); i++) {
prepareSource(i);
/*if (duplicateFlags.get(i) == null || !duplicateFlags.get(i)) {
final int index = i;
mediaSources.get(i).prepareSource(new Listener() {
#Override
public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
handleSourceInfoRefreshed(index, timeline, manifest);
}
});
}*/
}
}
private void prepareSource(int sourceindex) {
if (duplicateFlags.get(sourceindex) == null || !duplicateFlags.get(sourceindex)) {
final int index = sourceindex;
mediaSources.get(sourceindex).prepareSource(new Listener() {
#Override
public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
handleSourceInfoRefreshed(index, timeline, manifest);
}
});
}
}
#Override
public void maybeThrowSourceInfoRefreshError() throws IOException {
for (int i = 0; i < mediaSources.size(); i++) {
if (duplicateFlags.get(i) == null || !duplicateFlags.get(i)) {
mediaSources.get(i).maybeThrowSourceInfoRefreshError();
}
}
}
#Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
int sourceIndex = timeline.getSourceIndexForPeriod(index);
int periodIndexInSource = index - timeline.getFirstPeriodIndexInSource(sourceIndex);
MediaPeriod mediaPeriod = mediaSources.get(sourceIndex).createPeriod(periodIndexInSource, callback,
allocator, positionUs);
sourceIndexByMediaPeriod.put(mediaPeriod, sourceIndex);
return mediaPeriod;
}
#Override
public void releasePeriod(MediaPeriod mediaPeriod) {
int sourceIndex = sourceIndexByMediaPeriod.get(mediaPeriod);
sourceIndexByMediaPeriod.remove(mediaPeriod);
mediaSources.get(sourceIndex).releasePeriod(mediaPeriod);
}
#Override
public void releaseSource() {
for (int i = 0; i < mediaSources.size(); i++) {
if (duplicateFlags.get(i) == null || !duplicateFlags.get(i)) {
mediaSources.get(i).releaseSource();
}
}
}
private void handleSourceInfoRefreshed(int sourceFirstIndex, Timeline sourceTimeline,
Object sourceManifest) {
// Set the timeline and manifest.
timelines.add(sourceFirstIndex, sourceTimeline);
manifests.add(sourceFirstIndex, sourceManifest);
// Also set the timeline and manifest for any duplicate entries of the same source.
for (int i = sourceFirstIndex + 1; i < mediaSources.size(); i++) {
if (mediaSources.get(i).equals(mediaSources.get(sourceFirstIndex))) {
timelines.add(i, sourceTimeline);
manifests.add(i, sourceManifest);
}
}
for (Timeline timeline : timelines) {
if (timeline == null) {
// Don't invoke the listener until all sources have timelines.
return;
}
}
timeline = new DynamicTimeline(new ArrayList(timelines));
listener.onSourceInfoRefreshed(timeline, new ArrayList(manifests));
}
private static SparseArray<Boolean> buildDuplicateFlags(List<MediaSource> mediaSources) {
SparseArray<Boolean> duplicateFlags = new SparseArray<Boolean>();
IdentityHashMap<MediaSource, Void> sources = new IdentityHashMap<>(mediaSources.size());
for (int i = 0; i < mediaSources.size(); i++) {
MediaSource mediaSource = mediaSources.get(i);
if (!sources.containsKey(mediaSource)) {
sources.put(mediaSource, null);
} else {
duplicateFlags.setValueAt(i, true);
}
}
return duplicateFlags;
}
/**
* A {#link Timeline} that is the concatenation of one or more {#link Timeline}s.
*/
private static final class DynamicTimeline extends Timeline {
private final List<Timeline> timelines;
private final List<Integer> sourcePeriodOffsets;
private final List<Integer> sourceWindowOffsets;
public DynamicTimeline(List<Timeline> timelines) {
List<Integer> sourcePeriodOffsets = new ArrayList<>();
List<Integer> sourceWindowOffsets = new ArrayList<>();
int periodCount = 0;
int windowCount = 0;
for (Timeline timeline : timelines) {
periodCount += timeline.getPeriodCount();
windowCount += timeline.getWindowCount();
sourcePeriodOffsets.add(periodCount);
sourceWindowOffsets.add(windowCount);
}
this.timelines = timelines;
this.sourcePeriodOffsets = sourcePeriodOffsets;
this.sourceWindowOffsets = sourceWindowOffsets;
}
#Override
public int getWindowCount() {
return sourceWindowOffsets.get(sourceWindowOffsets.size() - 1);
}
#Override
public Window getWindow(int windowIndex, Window window, boolean setIds) {
int sourceIndex = getSourceIndexForWindow(windowIndex);
int firstWindowIndexInSource = getFirstWindowIndexInSource(sourceIndex);
int firstPeriodIndexInSource = getFirstPeriodIndexInSource(sourceIndex);
timelines.get(sourceIndex).getWindow(windowIndex - firstWindowIndexInSource, window, setIds);
window.firstPeriodIndex += firstPeriodIndexInSource;
window.lastPeriodIndex += firstPeriodIndexInSource;
return window;
}
#Override
public int getPeriodCount() {
return sourcePeriodOffsets.get(sourcePeriodOffsets.size() - 1);
}
#Override
public Period getPeriod(int periodIndex, Period period, boolean setIds) {
int sourceIndex = getSourceIndexForPeriod(periodIndex);
int firstWindowIndexInSource = getFirstWindowIndexInSource(sourceIndex);
int firstPeriodIndexInSource = getFirstPeriodIndexInSource(sourceIndex);
timelines.get(sourceIndex).getPeriod(periodIndex - firstPeriodIndexInSource, period, setIds);
period.windowIndex += firstWindowIndexInSource;
if (setIds) {
period.uid = Pair.create(sourceIndex, period.uid);
}
return period;
}
#Override
public int getIndexOfPeriod(Object uid) {
if (!(uid instanceof Pair)) {
return C.INDEX_UNSET;
}
Pair<?, ?> sourceIndexAndPeriodId = (Pair<?, ?>) uid;
if (!(sourceIndexAndPeriodId.first instanceof Integer)) {
return C.INDEX_UNSET;
}
int sourceIndex = (Integer) sourceIndexAndPeriodId.first;
Object periodId = sourceIndexAndPeriodId.second;
if (sourceIndex < 0 || sourceIndex >= timelines.size()) {
return C.INDEX_UNSET;
}
int periodIndexInSource = timelines.get(sourceIndex).getIndexOfPeriod(periodId);
return periodIndexInSource == C.INDEX_UNSET ? C.INDEX_UNSET
: getFirstPeriodIndexInSource(sourceIndex) + periodIndexInSource;
}
private int getSourceIndexForPeriod(int periodIndex) {
return Util.binarySearchFloor(sourcePeriodOffsets, periodIndex, true, false) + 1;
}
private int getFirstPeriodIndexInSource(int sourceIndex) {
return sourceIndex == 0 ? 0 : sourcePeriodOffsets.get(sourceIndex - 1);
}
private int getSourceIndexForWindow(int windowIndex) {
return Util.binarySearchFloor(sourceWindowOffsets, windowIndex, true, false) + 1;
}
private int getFirstWindowIndexInSource(int sourceIndex) {
return sourceIndex == 0 ? 0 : sourceWindowOffsets.get(sourceIndex - 1);
}
}
}
How can I save my current ImageView when I press onClick?
Im currently having the problem that the image that is next in line is being saved instead of the current actual image..
My Code for saving onLike
public class MainActivity extends Activity implements SwipeView.OnCardSwipedListener {
// Declaring variables
private final static int CARDS_MAX_ELEMENTS = 5;
private FrameLayout contentLayout;
private SwipeView mSwipeView;
private View addCardc41;
private Firebase mRef;
public ImageView imageLogo;
public ImageView imageview;
private static final String TAG = "MyActivity";
// Creating array of meals, getting them from the drawable folder
private int[] meals = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e,
R.drawable.f,
R.drawable.g,
R.drawable.h,
R.drawable.i,
R.drawable.j
};
// Declaring a counter for the next method
private int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe_view_demo);
contentLayout = (FrameLayout) findViewById(R.id.contentLayout);
imageLogo = (ImageView) findViewById(R.id.imageView3);
imageview = (ImageView) findViewById(R.id.imageView);
// Add the swipe view
mSwipeView = new SwipeView(this, R.id.imgSwipeLike, R.id.imgSwipeNope,
this);
contentLayout.addView(mSwipeView);
// Adding the cards initially with the maximum limits of cards.
for (int i = 0; i < CARDS_MAX_ELEMENTS; i++) {
addCard(i);
}
}
/**
* On clicked view.
*
* #param clickedView
* the clicked view
*/
public void onClickedView(View clickedView) {
switch (clickedView.getId()) {
case R.id.imgDisLike: {
mSwipeView.dislikeCard();
break;
}
case R.id.imgLike: {
mSwipeView.likeCard();
break;
}
}
}
#Override
public void onLikes() {
imageview.setDrawingCacheEnabled(true); //Add this line.
imageview.buildDrawingCache();
Bitmap bm=imageview.getDrawingCache();
OutputStream fOut = null;
Uri outputFileUri;
try {
File root = new File(Environment.getExternalStorageDirectory()
+ File.separator + "folder_name" + File.separator);
root.mkdirs();
File sdImageMainDirectory = new File(root, "myPicName.jpg");
outputFileUri = Uri.fromFile(sdImageMainDirectory);
fOut = new FileOutputStream(sdImageMainDirectory);
MediaScannerConnection.scanFile(this, new String[] { sdImageMainDirectory.getAbsolutePath() }, null, null);
} catch (Exception e) {
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
try {
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e){}
System.out.println("An Card removed");
// Add a card if you needed after any previous card swiped
addCard(0);
}
#Override
public void onDisLikes() {
System.out.println("An Card removed");
// Add a card if you needed after any previous card swiped
addCard(0);
}
#Override
public void onSingleTap() {
}
/**
* Adds the card to the swipe.
*/
private void addCard(int position) {
final View cardView = LayoutInflater.from(this).inflate(
R.layout.item_swipe_view, null);
final ImageView imgMeal = (ImageView) cardView
.findViewById(R.id.imgMeals);
imgMeal.setImageResource(meals[count]);
count++;
if (count == meals.length) {
count = 0;
}
// Add a card to the swipe view..
mSwipeView.addCard(cardView, position);
// Create OnClickListener for the CookBookActivity
// Declare Button for the Cookbook
Button btn = (Button) findViewById(R.id.button3);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, CookbookActivity.class));
}
});
// Check Authentication
mRef = new Firebase(Constants.FIREBASE_URL);
if (mRef.getAuth() == null) {
loadLoginView();
}
}
private void loadLoginView() {
Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
The Library that i'm using for the swiping
//
// credits to IntelliJ IDEA
// (powered by Fernflower decompiler)
package com.rk.lib.view;
import android.content.Context;
import android.os.Handler;
import android.os.Build.VERSION;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.View.OnTouchListener;
import android.view.animation.AlphaAnimation;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.FrameLayout.LayoutParams;
public class SwipeView extends FrameLayout {
private View mFocusedView;
private View mFocusedViewLike;
private View mFocusedViewNope;
private int mFocusedViewWidth;
private float mPreviousAlpha = 0.0F;
private Integer mLikeResource = Integer.valueOf(0);
private Integer mNopeResource = Integer.valueOf(0);
private static final int MAX_ELEMENTS = 3;
private static final long DELAY_SCROLL_RUNNABLE = 1L;
private static final int SCROLL_LENGTH = 5;
private int mScrolledPixelsX;
private int mScrolledPixelsY;
private int mNeedToScrollX;
private int mNeedToScrollY;
private int mTotalScrolledX;
private int mTotalScrolledY;
private int mScrollLengthX = 5;
private int mScrollLengthY = 5;
private boolean enableTouchSwipe = true;
private Context mContext;
private SwipeView.ScrollMode mScrollModeX;
private SwipeView.ScrollMode mScrollModeY;
private SwipeView.ScrollDirection mScrollDirection;
private int[] paddingX;
private int[] paddingYTop;
private int[] paddingYBottom;
private SwipeView.OnCardSwipedListener mOnCardSwipedListener;
private Handler mScrollHandler;
private Runnable mScrollRunnable;
private final SimpleOnGestureListener simpleOnGestureListener;
public SwipeView(Context context, Integer likeResource, Integer nopeResource, SwipeView.OnCardSwipedListener cardSwipeListener) {
super(context);
this.mScrollModeX = SwipeView.ScrollMode.NONE;
this.mScrollModeY = SwipeView.ScrollMode.NONE;
this.mScrollDirection = SwipeView.ScrollDirection.NONE;
this.paddingX = new int[]{0, 10, 20};
this.paddingYTop = new int[]{0, 10, 20};
this.paddingYBottom = new int[]{20, 10, 0};
this.mScrollHandler = new Handler();
this.mScrollRunnable = new Runnable() {
public void run() {
boolean scrollX;
boolean scrollY;
int scrollX1;
int scrollY1;
if(SwipeView.this.mScrollDirection == SwipeView.ScrollDirection.OUT) {
if(SwipeView.this.mNeedToScrollX <= 0 && SwipeView.this.mNeedToScrollY <= 0) {
SwipeView.this.mScrollHandler.removeCallbacks(SwipeView.this.mScrollRunnable);
SwipeView.this.removeView(SwipeView.this.mFocusedView);
if(SwipeView.this.mScrollModeX == SwipeView.ScrollMode.LEFT) {
SwipeView.this.mOnCardSwipedListener.onLikes();
} else if(SwipeView.this.mScrollModeX == SwipeView.ScrollMode.RIGHT) {
SwipeView.this.mOnCardSwipedListener.onDisLikes();
}
SwipeView.this.alignCardsPadding();
} else {
if(SwipeView.this.mNeedToScrollX < SwipeView.this.mScrollLengthX) {
SwipeView.this.mScrollLengthX = SwipeView.this.mNeedToScrollX;
SwipeView.this.mNeedToScrollX = 0;
} else {
SwipeView.this.mNeedToScrollX = SwipeView.this.mNeedToScrollX - SwipeView.this.mScrollLengthX;
}
if(SwipeView.this.mNeedToScrollY < SwipeView.this.mScrollLengthY) {
SwipeView.this.mScrollLengthY = SwipeView.this.mNeedToScrollY;
SwipeView.this.mNeedToScrollY = 0;
} else {
SwipeView.this.mNeedToScrollY = SwipeView.this.mNeedToScrollY - SwipeView.this.mScrollLengthY;
}
scrollX = false;
scrollY = false;
if(SwipeView.this.mScrollModeX == SwipeView.ScrollMode.LEFT) {
scrollX1 = -SwipeView.this.mScrollLengthX;
} else {
scrollX1 = SwipeView.this.mScrollLengthX;
}
if(SwipeView.this.mScrollModeY == SwipeView.ScrollMode.TOP) {
scrollY1 = -SwipeView.this.mScrollLengthY;
} else {
scrollY1 = SwipeView.this.mScrollLengthY;
}
SwipeView.this.mFocusedView.scrollBy(scrollX1, scrollY1);
SwipeView.this.mScrollHandler.postDelayed(SwipeView.this.mScrollRunnable, 1L);
}
} else if(SwipeView.this.mScrollDirection == SwipeView.ScrollDirection.IN) {
if(SwipeView.this.mTotalScrolledX <= 0 && SwipeView.this.mTotalScrolledY <= 0) {
SwipeView.this.mScrollHandler.removeCallbacks(SwipeView.this.mScrollRunnable);
SwipeView.this.mScrollDirection = SwipeView.ScrollDirection.NONE;
} else {
if(SwipeView.this.mTotalScrolledX < SwipeView.this.mScrollLengthX) {
SwipeView.this.mScrollLengthX = SwipeView.this.mTotalScrolledX;
SwipeView.this.mTotalScrolledX = 0;
} else {
SwipeView.this.mTotalScrolledX = SwipeView.this.mTotalScrolledX - SwipeView.this.mScrollLengthX;
}
if(SwipeView.this.mTotalScrolledY < SwipeView.this.mScrollLengthY) {
SwipeView.this.mScrollLengthY = SwipeView.this.mTotalScrolledY;
SwipeView.this.mTotalScrolledY = 0;
} else {
SwipeView.this.mTotalScrolledY = SwipeView.this.mTotalScrolledY - SwipeView.this.mScrollLengthY;
}
scrollX = false;
scrollY = false;
if(SwipeView.this.mScrollModeX == SwipeView.ScrollMode.LEFT) {
scrollX1 = SwipeView.this.mScrollLengthX;
} else {
scrollX1 = -SwipeView.this.mScrollLengthX;
}
if(SwipeView.this.mScrollModeY == SwipeView.ScrollMode.TOP) {
scrollY1 = -SwipeView.this.mScrollLengthY;
} else {
scrollY1 = SwipeView.this.mScrollLengthY;
}
SwipeView.this.mFocusedView.scrollBy(scrollX1, scrollY1);
SwipeView.this.mScrollHandler.postDelayed(SwipeView.this.mScrollRunnable, 1L);
}
}
}
};
this.simpleOnGestureListener = new SimpleOnGestureListener() {
public boolean onSingleTapConfirmed(MotionEvent e) {
SwipeView.this.mOnCardSwipedListener.onSingleTap();
return super.onSingleTapConfirmed(e);
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if(SwipeView.this.mFocusedView != null) {
SwipeView.this.mScrolledPixelsX = SwipeView.this.mScrolledPixelsX + (int)distanceX;
SwipeView.this.mScrolledPixelsY = SwipeView.this.mScrolledPixelsY + (int)distanceY;
SwipeView.this.mFocusedView.scrollBy((int)distanceX, (int)distanceY);
float alpha = (float)SwipeView.this.mScrolledPixelsX / (float)SwipeView.this.mFocusedViewWidth;
if(alpha > 0.0F) {
SwipeView.this.mFocusedViewNope.setVisibility(0);
SwipeView.this.mFocusedViewLike.setVisibility(8);
SwipeView.setAlpha(SwipeView.this.mFocusedViewNope, SwipeView.this.mPreviousAlpha, alpha);
SwipeView.this.mPreviousAlpha = alpha;
} else {
SwipeView.this.mFocusedViewNope.setVisibility(8);
SwipeView.this.mFocusedViewLike.setVisibility(0);
SwipeView.setAlpha(SwipeView.this.mFocusedViewLike, SwipeView.this.mPreviousAlpha, -alpha);
SwipeView.this.mPreviousAlpha = -alpha;
}
}
return true;
}
};
this.mContext = context;
this.mLikeResource = likeResource;
this.mNopeResource = nopeResource;
this.mOnCardSwipedListener = cardSwipeListener;
float density = this.getResources().getDisplayMetrics().density;
for(int gestureDetector = 0; gestureDetector < this.paddingX.length; ++gestureDetector) {
this.paddingX[gestureDetector] = (int)((float)this.paddingX[gestureDetector] * density);
this.paddingYTop[gestureDetector] = (int)((float)this.paddingYTop[gestureDetector] * density);
this.paddingYBottom[gestureDetector] = (int)((float)this.paddingYBottom[gestureDetector] * density);
}
final GestureDetector var7 = new GestureDetector(this.mContext, this.simpleOnGestureListener);
this.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(SwipeView.this.getChildCount() > 0) {
if(SwipeView.this.mScrollDirection != SwipeView.ScrollDirection.NONE) {
return false;
} else if(!SwipeView.this.enableTouchSwipe) {
return false;
} else {
var7.onTouchEvent(event);
switch(event.getAction()) {
case 0:
if(SwipeView.this.getChildCount() > 0) {
SwipeView.this.mFocusedView = SwipeView.this.getChildAt(SwipeView.this.getChildCount() - 1);
SwipeView.this.mFocusedViewLike = SwipeView.this.mFocusedView.findViewById(SwipeView.this.mLikeResource.intValue());
SwipeView.this.mFocusedViewNope = SwipeView.this.mFocusedView.findViewById(SwipeView.this.mNopeResource.intValue());
SwipeView.this.mFocusedViewWidth = SwipeView.this.mFocusedView.getWidth();
SwipeView.this.mFocusedView.setPadding(SwipeView.this.paddingX[0], 0, SwipeView.this.paddingX[0], 0);
}
SwipeView.this.resetScrollingValues();
break;
case 1:
SwipeView.this.alignCardsPadding();
if(SwipeView.this.mScrolledPixelsX < 0) {
SwipeView.this.mScrollModeX = SwipeView.ScrollMode.LEFT;
SwipeView.this.mTotalScrolledX = -SwipeView.this.mScrolledPixelsX;
} else {
SwipeView.this.mScrollModeX = SwipeView.ScrollMode.RIGHT;
SwipeView.this.mTotalScrolledX = SwipeView.this.mScrolledPixelsX;
}
if(SwipeView.this.mScrolledPixelsY < 0) {
SwipeView.this.mScrollModeY = SwipeView.ScrollMode.BOTTOM;
SwipeView.this.mTotalScrolledY = -SwipeView.this.mScrolledPixelsY;
} else {
SwipeView.this.mScrollModeY = SwipeView.ScrollMode.TOP;
SwipeView.this.mTotalScrolledY = SwipeView.this.mScrolledPixelsY;
}
SwipeView.this.detectSwipe();
}
return true;
}
} else {
return false;
}
}
});
}
public void addCard(View view, int position) {
if(this.getChildCount() <= 3 && position < 3) {
LinearLayout viewLayout = new LinearLayout(this.mContext);
viewLayout.setLayoutParams(new LayoutParams(-1, -1));
view.setLayoutParams(new LayoutParams(-1, -1));
viewLayout.addView(view);
viewLayout.setPadding(this.paddingX[position], this.paddingYTop[position], this.paddingX[position], this.paddingYBottom[position]);
this.addView(viewLayout, 0);
}
}
public void removeFocusedCard() {
this.removeView(this.mFocusedView);
this.alignCardsPadding();
}
private void alignCardsPadding() {
int i = 0;
for(int j = this.getChildCount() - 1; j >= 0; --j) {
this.getChildAt(j).setPadding(this.paddingX[i], this.paddingYTop[i], this.paddingX[i], this.paddingYBottom[i]);
++i;
}
this.mScrollDirection = SwipeView.ScrollDirection.NONE;
}
private void resetScrollingValues() {
this.mPreviousAlpha = 0.0F;
this.mNeedToScrollX = 0;
this.mScrolledPixelsX = 0;
this.mTotalScrolledX = 0;
this.mNeedToScrollY = 0;
this.mScrolledPixelsY = 0;
this.mTotalScrolledY = 0;
this.mScrollLengthX = 5;
this.mScrollLengthY = 5;
this.mScrollModeX = SwipeView.ScrollMode.NONE;
this.mScrollModeY = SwipeView.ScrollMode.NONE;
}
public void resetFocuedView() {
if(this.getChildCount() > 0) {
View mFocusedView = this.getChildAt(this.getChildCount() - 1);
View mFocusedViewLike = mFocusedView.findViewById(this.mLikeResource.intValue());
View mFocusedViewNope = mFocusedView.findViewById(this.mNopeResource.intValue());
setAlpha(mFocusedViewLike, 0.0F, 0.0F);
setAlpha(mFocusedViewNope, 0.0F, 0.0F);
mFocusedView.scrollTo(0, 0);
}
}
private void detectSwipe() {
int imageHalf = this.mFocusedView.getWidth() / 2;
this.mNeedToScrollX = this.mFocusedView.getWidth() - this.mTotalScrolledX;
if(this.mScrollDirection == SwipeView.ScrollDirection.NONE) {
if(this.mNeedToScrollX < imageHalf) {
this.mScrollDirection = SwipeView.ScrollDirection.OUT;
} else {
this.mScrollDirection = SwipeView.ScrollDirection.IN;
setAlpha(this.mFocusedViewLike, 0.0F, 0.0F);
setAlpha(this.mFocusedViewNope, 0.0F, 0.0F);
}
}
this.mScrollHandler.post(this.mScrollRunnable);
}
public void likeCard() {
if(this.getChildCount() > 0) {
this.mFocusedView = this.getChildAt(this.getChildCount() - 1);
this.mFocusedViewLike = this.mFocusedView.findViewById(this.mLikeResource.intValue());
this.mFocusedViewNope = this.mFocusedView.findViewById(this.mNopeResource.intValue());
if(this.mScrollDirection != SwipeView.ScrollDirection.NONE) {
return;
}
this.resetScrollingValues();
this.mScrollDirection = SwipeView.ScrollDirection.OUT;
this.mScrollModeX = SwipeView.ScrollMode.LEFT;
this.mFocusedViewLike.setVisibility(0);
setAlpha(this.mFocusedViewLike, 0.0F, 1.0F);
this.detectSwipe();
}
}
public void dislikeCard() {
if(this.getChildCount() > 0) {
this.mFocusedView = this.getChildAt(this.getChildCount() - 1);
this.mFocusedViewLike = this.mFocusedView.findViewById(this.mLikeResource.intValue());
this.mFocusedViewNope = this.mFocusedView.findViewById(this.mNopeResource.intValue());
if(this.mScrollDirection != SwipeView.ScrollDirection.NONE) {
return;
}
this.resetScrollingValues();
this.mScrollDirection = SwipeView.ScrollDirection.OUT;
this.mScrollModeX = SwipeView.ScrollMode.RIGHT;
this.mFocusedViewNope.setVisibility(0);
setAlpha(this.mFocusedViewNope, 0.0F, 1.0F);
this.detectSwipe();
}
}
public void setTouchable(boolean touchable) {
this.enableTouchSwipe = touchable;
}
public static void setAlpha(View view, float fromAlpha, float toAlpha) {
if(VERSION.SDK_INT < 11) {
AlphaAnimation alphaAnimation = new AlphaAnimation(fromAlpha, toAlpha);
alphaAnimation.setDuration(0L);
alphaAnimation.setFillAfter(true);
view.startAnimation(alphaAnimation);
} else {
view.setAlpha(toAlpha);
}
}
public interface OnCardSwipedListener {
void onLikes();
void onDisLikes();
void onSingleTap();
}
private static enum ScrollDirection {
IN,
OUT,
NONE;
private ScrollDirection() {
}
}
private static enum ScrollMode {
LEFT,
RIGHT,
TOP,
BOTTOM,
NONE;
private ScrollMode() {
}
}
}
ATTEMPT #3
This is the code that i've tried but I keep getting the same result (read comment below what I have done:
FrameLayout view = (FrameLayout)findViewById(R.id.contentLayout);
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
I believe the image you are trying to save is getting removed during the onSwipe due to the library code. I think you need to move your code to before the onLike is called.
You're also attempting to get a bitmap from the cache of the entire layout, rather than the wanted ImageView here:
bm=contentLayout.getDrawingCache();
You'll want to get your current card view as a View, then, from my understanding of your code, the ID of your actual ImageView containing the expected bitmap is R.id.imgMeals, so I the suggest replacing the line:
bm=contentLayout.getDrawingCache();
with the following:
ImageView imageView = (ImageView) cardView.findViewById(R.id.imgMeals);
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bm = drawable.getBitmap();
Move all of the below code from where you have it, to where I have marked //HERE!! in the following part of your code (or better, move it to a new method and call the method here).
// If the imageview of like is clicked
case R.id.imgLike: {
// HERE!!
// The imageview in the contentlayout will be swiped to the right
mSwipeView.likeCard();
break;
}
This is the code to me moved including the change I mention above:
View cardView = mSwipeView.getChildAt(mSwipeView.getChildCount() - 1);
ImageView imageView = (ImageView) cardView.findViewById(R.id.imgMeals);
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bm = drawable.getBitmap();
OutputStream fOut = null;
try {
// Save on my sd card
File root = new File(Environment.getExternalStorageDirectory()
// Making a folder name Food Inspiration
+ File.separator + "Food Inspiration" + File.separator);
root.mkdirs();
File sdImageMainDirectory = null;
// Loop for having a different name for every image
int i = 0;
do {
sdImageMainDirectory = new File(root, "pic-" + i + ".png");
i++;
} while (sdImageMainDirectory.exists());
fOut = new FileOutputStream(sdImageMainDirectory);
// Updates the gallery of your phone with the folder and the "liked" images in it
MediaScannerConnection.scanFile(this, new String[] { sdImageMainDirectory.getAbsolutePath() }, null, null);
// If something goes wrong
} catch (Exception e) {
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
// Compresses the actual bitmap image
try {
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e){}
I have a problem with my ImageViews.
At a certain time I disable it and make it invisible. Later in the program, but they should be re-enabled and visible. Unfortunately it does not work. I have often tried to find the bug with the debugger, but the corresponding code is not skipped. Nevertheless, the buttons in the app are not visible or enabled. Even the animated drawable does not start, even though it should. This should happen when calling from playanimation().
As this is my first app or program, the code is a bit unreadable.
Maybe can help me?
Here's the code:
I mean that part of the code:
case 1:
imageViewsleepbutton.setVisibility(View.VISIBLE);
imageViewfeedbutton.setVisibility(View.VISIBLE);
imageViewShowerbutton.setVisibility(View.VISIBLE);
imageViewPlaybutton.setVisibility(View.VISIBLE);
imageViewsleepbutton.setEnabled(true);
imageViewfeedbutton.setEnabled(true);
imageViewShowerbutton.setEnabled(true);
imageViewPlaybutton.setEnabled(true);
Settings.setLevel(2, context);
helper.setCorrectPet();
helper.playAnimation();
textviewStatus.setText(activity.getString(R.string.baby));
break;
In that class:
package at.android.virtualpet;
import java.util.Random;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class TimerC{
//TODO Try-Catch Timer
private Handler handler;
Toast toast;
private ImageView imageViewsleepbutton;
private ImageView imageViewfeedbutton;
private ImageView imageViewShowerbutton;
private ImageView imageViewPlaybutton;
private TextView textviewStatus;
private int intervall;
private Helper helper;
private Context context;
Activity activity;
public TimerC(Context context, Activity activity, int intervall){
this.context = context;
this.activity = activity;
this.intervall = intervall;
}
public void startTimer() {
boolean b, resume;
b = Settings.getFirstStart(context);
resume = Settings.getResumeStatus(context);
handler = new Handler();
helper = new Helper(context, activity);
if (b == true) {
Settings.setFirstStart(false, context);
handler.postDelayed(timedTask, 45000); //45000
}
else {
if (resume == true) {
helper.resumeStats();
Settings.setResumeStatus(false, context);
}
handler.postDelayed(timedTask, intervall);
}
}
public void stopTimer() {
handler.removeCallbacks(timedTask);
}
private void changePet() {
int stufe;
int progress;
imageViewsleepbutton = (ImageView) activity.findViewById(R.id.ImageViewsleepbutton);
imageViewfeedbutton = (ImageView) activity.findViewById(R.id.imageViewfeedbutton);
textviewStatus = (TextView) activity.findViewById(R.id.textViewStatus);
imageViewShowerbutton = (ImageView) activity.findViewById(R.id.imageViewShowerButton);
imageViewPlaybutton = (ImageView) activity.findViewById(R.id.imageViewPlayButton);
stufe = Settings.getLevel(context);
progress = Settings.getLevelProgress(context);
if (progress <= 0 || stufe == 1) {
switch(stufe) {
case 1:
imageViewsleepbutton.setVisibility(View.VISIBLE);
imageViewfeedbutton.setVisibility(View.VISIBLE);
imageViewShowerbutton.setVisibility(View.VISIBLE);
imageViewPlaybutton.setVisibility(View.VISIBLE);
imageViewsleepbutton.setEnabled(true);
imageViewfeedbutton.setEnabled(true);
imageViewShowerbutton.setEnabled(true);
imageViewPlaybutton.setEnabled(true);
Settings.setLevel(2, context);
helper.setCorrectPet();
helper.playAnimation();
textviewStatus.setText(activity.getString(R.string.baby));
break;
case 2:
Settings.setLevel(3, context);
helper.setCorrectPet();
helper.playAnimation();
textviewStatus.setText(activity.getString(R.string.teen));
break;
case 3:
Settings.setLevel(4, context);
helper.setCorrectPet();
helper.playAnimation();
textviewStatus.setText(activity.getString(R.string.adult));
break;
}
Settings.setLevelProgress(1000, context);
}
}
private void changeStats() {
int hunger;
int progress;
int stufe;
int sleep;
int fun;
int dirty;
int level;
int xp;
boolean day;
boolean firststart;
Random randInt = new Random();
int promp = 1; //progress multiplikator
int minushunger = randInt.nextInt(4)+3;
int minussleep = 3;
int sleepnight = 15;
int hungernight = randInt.nextInt(3)+2;
int minusdirty = randInt.nextInt(4)+2;
int minusfun = randInt.nextInt(2)+2;
int dirtynight = minusdirty;
int funnight = minusfun;
hunger = Settings.getHunger(context);
progress = Settings.getLevelProgress(context);
fun = Settings.getFun(context);
dirty = Settings.getDirty(context);
stufe = Settings.getLevel(context);
sleep = Settings.getSleep(context);
level = Settings.getLevel(context);
firststart = Settings.getFirstStart(context);
xp = Settings.getXP(context);
day = Settings.getDay(context);
if ((firststart == false) && (level != 1)) {
if (day == true) {
hunger = hunger - minushunger;
sleep = sleep - minussleep;
dirty = dirty - minusdirty;
fun = fun - minusfun;
} else {
hunger = hunger - hungernight;
sleep = sleep + sleepnight;
dirty = dirty - dirtynight;
fun = fun - funnight;
}
if(sleep > 100) {
sleep = 100;
helper.wakeup();
}
if(hunger < -5 ) {hunger = -5;}
if(sleep < -5) {sleep = -5;}
if(hunger > 110) {hunger = 110;}
if(dirty < -15 ) {dirty = -15;}
if(fun < -15 ) {fun = -15;}
if(dirty > 110) {dirty = 110;}
if(fun > 110) {fun = 110;}
Settings.setSleep(sleep, context);
Settings.setHunger(hunger, context);
Settings.setDirty(dirty, context);
Settings.setFun(fun, context);
//promp = 1
if ((sleep < 0) && (hunger < 0) && (dirty < 20) && (fun < 20)) {promp = 0;};
if ((sleep > 90) && (hunger > 90) && (dirty > 75) && (fun > 75)) {promp = 2;};
switch(stufe) {
case 1:
//Stufe 1 ist Ei. Das Ei schlüpft automatisch nach x Sek
break;
case 2:
progress = progress - (5 * promp);
break;
case 3:
progress = progress - (4 * promp);
break;
case 4:
progress = progress - (3 * promp);
break;
}
xp = xp + 4*promp;
Settings.setXP(xp, context);
helper.setCorrectPet();
helper.checkLevel();
Settings.setLevelProgress(progress, context);
helper.checkStatus();
}
}
private Runnable timedTask = new Runnable(){
#Override
public void run() {
changePet();
changeStats(); //Werte ändern und Meldungen ausgeben
helper.updateprogress();
helper.updateDebugFields();
handler.postDelayed(timedTask, intervall);
}};
}
and the playanimation() in an other class. This class has context an the activity from MainActivity.
public void playAnimation() {
imageViewPet = (ImageView)activity.findViewById(R.id.imageViewPet);
if (imageViewPet.getDrawable() instanceof AnimationDrawable) {
animatedaotori = (AnimationDrawable)imageViewPet.getDrawable();
Handler handler = new Handler(activity.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
animatedaotori.start();
}
}, 1500);
}
}