Как реализовать onBackPressed () во фрагментах?

У меня был аналогичный вопрос, где я хотел только дату, когда была сделана фотография, и ни одна из вышеперечисленных проблем не может решить мою проблему простым способом (например, без внешних библиотек), так что вот все данные, которые я мог бы найти, вы можете извлечь из изображения после выбора его с помощью сборщика:

// Inside whatever implements UIImagePickerControllerDelegate
@import AssetsLibrary;

// ... your other code here ...

@implementation MYImagePickerDelegate

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = info[UIImagePickerControllerMediaType];
    UIImage *originalImage = info[UIImagePickerControllerOriginalImage];
    UIImage *editedImage = info[UIImagePickerControllerEditedImage];
    NSValue *cropRect = info[UIImagePickerControllerCropRect];
    NSURL *mediaUrl = info[UIImagePickerControllerMediaURL];
    NSURL *referenceUrl = info[UIImagePickerControllerReferenceURL];
    NSDictionary *mediaMetadata = info[UIImagePickerControllerMediaMetadata];

    NSLog(@"mediaType=%@", mediaType);
    NSLog(@"originalImage=%@", originalImage);
    NSLog(@"editedImage=%@", editedImage);
    NSLog(@"cropRect=%@", cropRect);
    NSLog(@"mediaUrl=%@", mediaUrl);
    NSLog(@"referenceUrl=%@", referenceUrl);
    NSLog(@"mediaMetadata=%@", mediaMetadata);

    if (!referenceUrl) {
        NSLog(@"Media did not have reference URL.");
    } else {
        ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
        [assetsLib assetForURL:referenceUrl
                   resultBlock:^(ALAsset *asset) {
                       NSString *type = 
                           [asset valueForProperty:ALAssetPropertyType];
                       CLLocation *location = 
                           [asset valueForProperty:ALAssetPropertyLocation];
                       NSNumber *duration = 
                           [asset valueForProperty:ALAssetPropertyDuration];
                       NSNumber *orientation = 
                           [asset valueForProperty:ALAssetPropertyOrientation];
                       NSDate *date = 
                           [asset valueForProperty:ALAssetPropertyDate];
                       NSArray *representations = 
                           [asset valueForProperty:ALAssetPropertyRepresentations];
                       NSDictionary *urls = 
                           [asset valueForProperty:ALAssetPropertyURLs];
                       NSURL *assetUrl = 
                           [asset valueForProperty:ALAssetPropertyAssetURL];

                       NSLog(@"type=%@", type);
                       NSLog(@"location=%@", location);
                       NSLog(@"duration=%@", duration);
                       NSLog(@"assetUrl=%@", assetUrl);
                       NSLog(@"orientation=%@", orientation);
                       NSLog(@"date=%@", date);
                       NSLog(@"representations=%@", representations);
                       NSLog(@"urls=%@", urls);
                   }
                  failureBlock:^(NSError *error) {
                      NSLog(@"Failed to get asset: %@", error);
                  }];
    }

    [picker dismissViewControllerAnimated:YES
                               completion:nil];
}

@end

Поэтому, когда вы выбираете изображение, вы получаете вывод, который выглядит так (включая дату!):

mediaType=public.image
originalImage=<UIImage: 0x7fb38e00e870> size {1280, 850} orientation 0 scale 1.000000
editedImage=<UIImage: 0x7fb38e09e1e0> size {640, 424} orientation 0 scale 1.000000
cropRect=NSRect: {{0, 0}, {1280, 848}}
mediaUrl=(null)
referenceUrl=assets-library://asset/asset.JPG?id=AC072879-DA36-4A56-8A04-4D467C878877&ext=JPG
mediaMetadata=(null)
type=ALAssetTypePhoto
location=(null)
duration=ALErrorInvalidProperty
assetUrl=assets-library://asset/asset.JPG?id=AC072879-DA36-4A56-8A04-4D467C878877&ext=JPG
orientation=0
date=2014-07-14 04:28:18 +0000
representations=(
    "public.jpeg"
)
urls={
    "public.jpeg" = "assets-library://asset/asset.JPG?id=AC072879-DA36-4A56-8A04-4D467C878877&ext=JPG";
}

В любом случае, надеюсь, что кто-то еще кого-нибудь спасет.

392
задан Sufian 9 August 2016 в 13:33
поделиться

7 ответов

Ничто из этого не легко реализовать и не будет функционировать оптимальным образом.

Фрагменты имеют вызов метода onDetach, который выполнит эту работу.

@Override
    public void onDetach() {
        super.onDetach();
        PUT YOUR CODE HERE
    }

ЭТО ДЕЛАЕТ РАБОТУ.

45
ответ дан Sterling Diaz 9 August 2016 в 13:33
поделиться

Если вы используете EventBus, это, вероятно, гораздо более простое решение:

В вашем фрагменте:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    EventBus.getDefault().register(this);
}

@Override
public void onDetach() {
    super.onDetach();
    EventBus.getDefault().unregister(this);
}


// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
    getSupportFragmentManager().popBackStack();
}

и в вашем классе деятельности вы можете определить :

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
    super.onBackPressed();
}

@Override
public void onBackPressed() {
    EventBus.getDefault().post(new BackPressedMessage(true));
}

BackPressedMessage.java - это просто объект POJO

Это очень чисто и нет проблем с интерфейсом / реализацией.

6
ответ дан Akshat 9 August 2016 в 13:33
поделиться

Если Вы используете androidx.appcompat:appcompat:1.1.0, или выше затем Вас может добавить OnBackPressedCallback к Вашему фрагменту следующим образом

requireActivity()
    .onBackPressedDispatcher
    .addCallback(this, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            Log.d(TAG, "Fragment back pressed invoked")
            // Do custom work here    

            // if you want onBackPressed() to be called as normal afterwards
            if (isEnabled) {
                isEnabled = false
                requireActivity().onBackPressed()
            }
        }
    }
)

, См. https://developer.android.com/guide/navigation/navigation-custom-back

5
ответ дан 22 November 2019 в 23:24
поделиться
   @Override
   public boolean onKeyDown(int keyCode, KeyEvent event)
    {
       if ((keyCode == KeyEvent.KEYCODE_BACK))
  {
           finish();
    }
       return super.onKeyDown(keyCode, event);
    }

Просто Комментарий Любой Ключ вниз имел отношение, метод теперь addToBackStack будет работать. спасибо

-1
ответ дан 22 November 2019 в 23:24
поделиться

Необходимо переопределить onBackPressed () со слушателем фрагмента. Вот то, как:

https://stackoverflow.com/a/51228447/7451779

0
ответ дан 22 November 2019 в 23:24
поделиться

В моем решении (Kotlin);

я использую функцию onBackAlternative в качестве параметра на [1 111] BaseActivity.

BaseActivity

abstract class BaseActivity {

    var onBackPressAlternative: (() -> Unit)? = null

    override fun onBackPressed() {
        if (onBackPressAlternative != null) {
            onBackPressAlternative!!()
        } else {
            super.onBackPressed()
        }
    }
}

у меня есть функция для набора onBackPressAlternative на [1 113] BaseFragment.

BaseFragment

abstract class BaseFragment {

     override fun onStart() {
        super.onStart()
        ...
        setOnBackPressed(null) // Add this
     }

     fun setOnBackPressed(onBackAlternative: (() -> Unit)?) {
         (activity as BaseActivity<*, *>).onBackPressAlternative = onBackAlternative
     }
}

Затем мой onBackPressAlternative готов использовать на фрагментах.

Фрагменты Sub

class LoginFragment : BaseFragment {

    override fun onStart() {
        super.onStart()
        ...
        setOnBackPressed {
            // Finally, you can write your custom onBackPressed function to here
        }
    }
}
0
ответ дан 22 November 2019 в 23:24
поделиться

Обеспечение пользовательской задней навигации путем обработки onBackPressed теперь более легко с обратными вызовами во фрагменте.

class MyFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val onBackPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (true == conditionForCustomAction) {
                    myCustomActionHere()
                } else  NavHostFragment.findNavController(this@MyFragment).navigateUp();    
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(
        this, onBackPressedCallback
    )
    ...
}

, Если Вы хотите обратное действие по умолчанию на основе некоторого условия, можно использовать:

 NavHostFragment.findNavController(this@MyFragment).navigateUp();
0
ответ дан 22 November 2019 в 23:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: