Last active
January 15, 2017 10:52
-
-
Save Sroka/df4a56cd8c692e6f5541e5a691792806 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example; | |
import android.os.Build; | |
import android.view.View; | |
import java.util.concurrent.atomic.AtomicInteger; | |
/** | |
* Created by srokowski.maciej@gmail.com on 16.11.16. | |
*/ | |
public class ViewIdGenerator { | |
/** | |
* Unique view id generator, like the one used in {@link View} class for view id generation. | |
* Since we can't access the generator within the {@link View} class before API 17, we create | |
* the same generator here. This creates a problem of two generator instances not knowing about | |
* each other, and we need to take care that one does not generate the id already generated by other one. | |
* <p> | |
* We know that all integers higher than 16 777 215 are reserved for aapt-generated identifiers | |
* (source: {@link View#generateViewId()}, so we make sure to never generate a value that big. | |
* We also know that generator within the {@link View} class starts at 1. | |
* We set our generator to start counting at 15 000 000. This gives us enough space | |
* (15 000 000 - 16 777 215), while making sure that generated IDs are unique, unless ILocationChooserView generates | |
* more than 15M IDs, which should never happen. | |
*/ | |
private static final AtomicInteger viewIdGenerator = new AtomicInteger(15000000); | |
/** | |
* Generate a value suitable for use in {@link View#setId(int)}. | |
* This value will not collide with ID values generated at build time by aapt for R.id. | |
* | |
* @return a generated ID value | |
*/ | |
public static int generateViewId() { | |
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { | |
return generateUniqueViewId(); | |
} else { | |
return View.generateViewId(); | |
} | |
} | |
private static int generateUniqueViewId() { | |
while (true) { | |
final int result = viewIdGenerator.get(); | |
// aapt-generated IDs have the high byte nonzero; clamp to the range under that. | |
int newValue = result + 1; | |
if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0. | |
if (viewIdGenerator.compareAndSet(result, newValue)) { | |
return result; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example; | |
import android.os.Bundle; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import java.util.HashMap; | |
/** | |
* Created by srokowski.maciej@gmail.com on 16.11.16. | |
*/ | |
public class ViewIdRestorer { | |
private static final String TAG_ID_MAP_KEY = "TAG_ID_MAP_KEY"; | |
private HashMap<String, Integer> tagIdMap = new HashMap<>(); | |
public int getId(String tag) { | |
if (tagIdMap.containsKey(tag)) { | |
return tagIdMap.get(tag); | |
} else { | |
final int viewId = ViewIdGenerator.generateViewId(); | |
tagIdMap.put(tag, viewId); | |
return viewId; | |
} | |
} | |
public void onCreate(@Nullable Bundle savedInstanceState) { | |
if (savedInstanceState != null) { | |
final HashMap<String, Integer> savedTagIdMap = (HashMap<String, Integer>) savedInstanceState.getSerializable(TAG_ID_MAP_KEY); | |
tagIdMap.putAll(savedTagIdMap); | |
} | |
} | |
public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { | |
final HashMap<String, Integer> savedTagIdMap = (HashMap<String, Integer>) savedInstanceState.getSerializable(TAG_ID_MAP_KEY); | |
tagIdMap.putAll(savedTagIdMap); | |
} | |
public void onSaveInstanceState(@NonNull Bundle outState) { | |
outState.putSerializable(TAG_ID_MAP_KEY, tagIdMap); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment