I am a newbie in Android developing and i try to understand how to use callbacks in interfaces.
I am use "Color-pick-preference" library in my app. I need it to change different settings, for example background color. And i want to change in runtime, without refresh activities.
This is how i do it now:
Color-picker-preference have three main classes:
ColorPickerView (as I understand it show color panel and send user choise via callback to ColorPickerDialog)
ColorPickerDialog (this class show preferebce dialog window includes color panel, submit color button etc. And send user choise data further in ColorPickerPreference)
and ColorPicerPreference wich save user choise in Shared Preferences.
I described very superficially, if you'll excuse me.
Parts of these three files
ColorPickerView
***
***
private OnColorChangedListener mListener;
***
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
***
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean update = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
update = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_MOVE:
update = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_UP:
mStartTouchPoint = null;
update = moveTrackersIfNeeded(event);
break;
}
if (update) {
if (mListener != null) {
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
return true;
}
return super.onTouchEvent(event);
}
***
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener;
}
***
public void setColor(int color, boolean callback) {
int alpha = Color.alpha(color);
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
mAlpha = alpha;
mHue = hsv[0];
mSat = hsv[1];
mVal = hsv[2];
if (callback && mListener != null) {
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
}
ColorPickerDialog
***
public class ColorPickerDialog
extends
Dialog
implements
ColorPickerView.OnColorChangedListener,
View.OnClickListener, ViewTreeObserver.OnGlobalLayoutListener ...
***
private OnColorChangedListener mListener;
***
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
***
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mLayout = inflater.inflate(R.layout.dialog_color_picker, null);
mLayout.getViewTreeObserver().addOnGlobalLayoutListener(this);
mOrientation = getContext().getResources().getConfiguration().orientation;
setContentView(mLayout);
setTitle(R.string.dialog_color_picker);
mColorPicker = (ColorPickerView) mLayout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) mLayout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) mLayout.findViewById(R.id.new_color_panel);
mHexVal = (EditText) mLayout.findViewById(R.id.hex_val);
mHexVal.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
mHexDefaultTextColor = mHexVal.getTextColors();
mHexVal.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
String s = mHexVal.getText().toString();
if (s.length() > 5 || s.length() < 10) {
try {
int c = ColorPickerPreference.convertToColorInt(s.toString());
mColorPicker.setColor(c, true);
mHexVal.setTextColor(mHexDefaultTextColor);
} catch (IllegalArgumentException e) {
mHexVal.setTextColor(Color.RED);
}
} else {
mHexVal.setTextColor(Color.RED);
}
return true;
}
return false;
}
});
((LinearLayout) mOldColor.getParent()).setPadding(
Math.round(mColorPicker.getDrawingOffset()),
0,
Math.round(mColorPicker.getDrawingOffset()),
0
);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
***
#Override
public void onColorChanged(int color) {
mNewColor.setColor(color);
if (mHexValueEnabled)
updateHexValue(color);
}
***
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener;
}
ColorPickerPreference
public class ColorPickerPreference
extends
Preference
implements
Preference.OnPreferenceClickListener,
ColorPickerDialog.OnColorChangedListener ...
***
#Override
public void onColorChanged(int color) {
if (isPersistent()) {
persistInt(color);
}
mValue = color;
setPreviewColor();
try {
getOnPreferenceChangeListener().onPreferenceChange(this, color);
} catch (NullPointerException e) {
}
notifyChanged();
}
***
protected void showDialog(Bundle state) {
mDialog = new ColorPickerDialog(getContext(), mValue);
mDialog.setOnColorChangedListener(this);
if (mAlphaSliderEnabled) {
mDialog.setAlphaSliderVisible(true);
}
if (mHexValueEnabled) {
mDialog.setHexValueEnabled(true);
}
if (state != null) {
mDialog.onRestoreInstanceState(state);
}
mDialog.show();
}
And what i try to do in my MainActivity
public class MainActivity extends AppCompatActivity implements
ColorPickerDialog.OnColorChangedListener {
public ColorPickerDialog cpd;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//return super.onOptionsItemSelected(item);
Integer id = item.getItemId();
switch (id) {
case R.id.menu_action_settings:
Intent i = new Intent(this, SettingActivity.class);
startActivity(i);
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cpd = new ColorPickerDialog(this,Color.BLACK);
cpd.setOnColorChangedListener(this);
setContentView(R.layout.activity_main);
}
public void onColorChanged(int color) {
RelativeLayout main_scroll_view = (RelativeLayout)findViewById(R.id.activity_main_rel_layout);
System.out.println("AIM ALIVE!");
main_scroll_view.setBackgroundColor(color);
}
}
But when i change color in ColorPickerPreference widget -nothing happens. the background color does not change and my System.out.println does not work ?
Sorry for chaotic presentation and thank you for your answers.
I too myself more of a challenge) Solved the problem by simply adding the onResume method in Mainactivity and check the Shared Preference and then setting the background color in the resulting value.
Where do you declare the action so you could show/open the dialog?
SettingActivity
***
public static class SettingsFragment extends PreferenceFragment {
PrefernceAnimation pa;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String settings = getArguments().getString("settings");
if ("colors".equals(settings)) {
addPreferencesFromResource(R.xml.preference_fragment_colors);
} else if ("sounds".equals(settings)) {
addPreferencesFromResource(R.xml.preference_fragment_sounds);
}
else if ("animation".equals(settings)) {
addPreferencesFromResource(R.xml.preference_fragment_animation);
}
}
}
and preference_headers.xml
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="com.dosomeweb.mika.babypic.SettingActivity$SettingsFragment"
android:title="#string/pref_main_title_colors"
android:summary="#string/pref_main_summery_colors">
<extra
android:name="settings"
android:value="colors"/>
</header>
<header
android:fragment="com.dosomeweb.mika.babypic.SettingActivity$SettingsFragment"
android:title="#string/pref_main_title_sounds"
android:summary="#string/pref_main_summery_sounds">
<extra
android:name="settings"
android:value="sounds"/>
</header>
<header
android:fragment="com.dosomeweb.mika.babypic.SettingActivity$SettingsFragment"
android:title="#string/pref_main_title_animation"
android:summary="#string/pref_main_summery_animation">
<extra
android:name="settings"
android:value="animation"/>
</header>
just in case prference_fragment_colors.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="pref_bg_color"
android:title="#string/pref_title_layout_bg_color"
android:summary="#string/pref_summary_layout_bg_color"
android:defaultValue="#color/colorAccent"/>
</PreferenceScreen>
Why are you creating so many different interface? Why not use 1 interface and link it all together since the callback have the same parameter.
Related
Abstract
The application consists of 3 main screens each of which has a RecyclerView. However I experience a strange problem with selection tracker after restoring its instance. As you will see in the code listing; I use a boolean called restoreSelection if there was selection saved in the bundle, and then I check this flag in the observer of Bolge items so that I can recreate the ActionMode appropriately since it will show selection information in "selection count / item count" format.
I have a listing fragment called BolgeListeleme.java and an adapter of RecyclerView.Adapter type called BolgeListelemeAdaptoru.java which I set the hasStableIds property to true. I will list the code but omit the unrelated parts.
What I want to achieve
What I want to achieve is to restore selection along with the contextual action bar (ActionMode) when navigating between screens so that I can recreate the ActionMode.
The problem
Selection tracker restores the selections successfully but after a while its onSelectionChanged callback is called (not by my trigger) and after each call, the selection is deleted one by one.
Here is a log output that shows the changes that happens on the selection after the restoration:
I/BolgeListeleme: onSelectionChanged: 1 - Selection{primary{size=1, entries=[12]}, provisional{size=0, entries=[]}}
I/BolgeListeleme: onSelectionChanged: 2 - Selection{primary{size=2, entries=[12, 29]}, provisional{size=0, entries=[]}}
I/BolgeListeleme: onSelectionChanged: 3 - Selection{primary{size=3, entries=[12, 29, 26]}, provisional{size=0, entries=[]}}
>>>HERE I SWITCH TO THE FRAGMENT CALLED AygitListeleme
D/AygitListeleme: Listeleme kipi değişti: 2
D/AygitListelemeAdaptoru: setListelemeKipi: listelemeKipi: 0, kip: 106, tamGuncelleme: false
D/AygitListeleme: Kayıttan alınan kip: 2
D/AygitListeleme: Nokta sayısı: 3
I/BolgeListeleme: onSelectionChanged: 0 - size=0, items=[]
D/AygitListeleme: onResume:
D/AygitListeleme: onPause:
>>> THEN I SWITCH BACK TO THE PREVIOUS ONE
W/EventsRelays: Item change notification received for unknown item: 12
W/EventsRelays: Item change notification received for unknown item: 29
W/EventsRelays: Item change notification received for unknown item: 26
I/BolgeListeleme: onViewCreated: hasSelection true; count 3
>>> THE PREVIOUS SELECTION HAS BEEN RESTORED
W/EventsRelays: Item change notification received for unknown item: 12
I/BolgeListeleme: onSelectionChanged: 2 - Selection{primary{size=2, entries=[29, 26]}, provisional{size=0, entries=[]}}
W/EventsRelays: Item change notification received for unknown item: 29
I/BolgeListeleme: onSelectionChanged: 1 - Selection{primary{size=1, entries=[26]}, provisional{size=0, entries=[]}}
W/EventsRelays: Item change notification received for unknown item: 26
I/BolgeListeleme: onSelectionChanged: 0 - size=0, items=[]
I/BolgeListeleme: onSelectionChanged: 0 - size=0, items=[]
>>> HERE WHEN I NEED TO PROCESS THE SELECTION TO RECREATE THE ActionMode,
>>> THE SELECTION CLEARED DOWN TO ZERO WITHOUT MY TRIGGER
I/BolgeListeleme: onViewCreated: selection 0
D/DefaultSelectionTracker: Ignoring onDataSetChange. No active selection.
D/DefaultSelectionTracker: Ignoring onDataSetChange. No active selection.
BolgeListelemeAdaptoru.java
public class BolgeListelemeAdaptoru extends RecyclerView.Adapter<BolgeListelemeAdaptoru.BolgeVH> {
private static final String TAG = BolgeListelemeAdaptoru.class.getSimpleName();
private final List<Bolge> bolgeler;
private SelectionTracker<Long> st;
public BolgeListelemeAdaptoru() {
setHasStableIds(true);
bolgeler = new ArrayList<>();
}
public void selectionTrackerKur(#NonNull SelectionTracker<Long> selectionTracker) {
st = selectionTracker;
}
#NonNull
#Override
public BolgeVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
HimBolgeModeliBinding bolgeModeliBinding =
HimBolgeModeliBinding.inflate(
LayoutInflater.from(parent.getContext()), parent, false);
return new BolgeVH(bolgeModeliBinding, tuketici);
}
#Override
public void onBindViewHolder(#NonNull BolgeVH holder, int position) {
Bolge b = bolgeler.get(position);
holder.bind(b, st);
}
#Override
public void onBindViewHolder(#NonNull BolgeVH holder, int position, #NonNull List<Object> payloads) {
if(payloads.isEmpty()) {
onBindViewHolder(holder, position);
} else {
for(Object payload: payloads) {
if(payload instanceof String &&
payload.equals(SelectionTracker.SELECTION_CHANGED_MARKER)) {
holder.secimKur(st);
}
}
}
}
#Override
public int getItemCount() {
return bolgeler.size();
}
#Override
public long getItemId(int position) {
return bolgeler.get(position).id;
}
public void update(List<Bolge> bolgeler) {
this.bolgeler.clear();
if(bolgeler == null || bolgeler.isEmpty()) return;
this.bolgeler.addAll(bolgeler);
notifyDataSetChanged();
}
static class BolgeVH extends RecyclerView.ViewHolder implements View.OnClickListener {
private final HimBolgeModeliBinding binding;
private Bolge bolge;
private final ItemDetailsLookup.ItemDetails<Long> details = new ItemDetailsLookup.ItemDetails<Long>() {
#Override
public int getPosition() {
return getBindingAdapterPosition();
}
#Nullable
#Override
public Long getSelectionKey() {
return getItemId();
}
};
public BolgeVH(#NonNull HimBolgeModeliBinding himBolgeModeliBinding, BolgeOlayTuketici tuketici) {
super(himBolgeModeliBinding.getRoot());
binding = himBolgeModeliBinding;
this.tuketici = tuketici;
}
#Override
public void onClick(View v) {
}
public ItemDetailsLookup.ItemDetails<Long> getItemDetails() {
return details;
}
public void bind(Bolge bolge, SelectionTracker<Long> st) {
this.bolge = bolge;
adKur(bolge);
noktaSayimiKur(bolge);
secimKur(st);
binding.getRoot().setOnClickListener(this);
}
void adKur(Bolge bolge) {
binding.tvBolgeAdi.setText(bolge.adi);
}
void noktaSayimiKur(Bolge bolge) {
String s = bolge.noktaSayimi == -1 ? "?"
: binding.getRoot().getContext().getResources()
.getQuantityString(R.plurals.n_aygit, bolge.noktaSayimi, bolge.noktaSayimi);
binding.tvAygitSayisi.setText(s);
}
void secimKur(SelectionTracker<Long> st) {
Log.i(TAG, "secimKur: "+st.getSelection().size());
boolean secili = st.isSelected(details.getSelectionKey());
binding.getRoot().setActivated(secili);
}
}
public static class BolgeDetailsLookup extends ItemDetailsLookup<Long> {
private final RecyclerView rv;
public BolgeDetailsLookup(RecyclerView rv) {
this.rv = rv;
}
#Nullable
#Override
public ItemDetails<Long> getItemDetails(#NonNull MotionEvent e) {
View v = rv.findChildViewUnder(e.getX(), e.getY());
if(v != null) {
RecyclerView.ViewHolder vh = rv.getChildViewHolder(v);
if(vh instanceof BolgeVH)
return ((BolgeVH) vh).getItemDetails();
}
return null;
}
}
}
BolgeListeleme
public class BolgeListeleme extends Fragment implements BolgeListelemeAdaptoru.BolgeOlayTuketici, ActionMode.Callback {
private static final String TAG = BolgeListeleme.class.getSimpleName();
private HimBolgeListelemeBinding binding;
private BolgeListelemeAdaptoru adaptor;
private SelectionTracker<Long> st;
private ActionMode actionMode;
private boolean restoreSelection;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
binding = HimBolgeListelemeBinding.inflate(inflater, container, false);
return binding.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
LinearLayoutManager layoutManager = new LinearLayoutManager(binding.bolgeListeleyici.getContext());
MaterialDividerItemDecoration mdid =
new MaterialDividerItemDecoration(requireContext(), layoutManager.getOrientation());
mdid.setLastItemDecorated(false);
adaptor = new BolgeListelemeAdaptoru();
binding.bolgeListeleyici.setLayoutManager(layoutManager);
binding.bolgeListeleyici.addItemDecoration(mdid);
binding.bolgeListeleyici.setAdapter(adaptor);
st = new SelectionTracker.Builder<>(
getClass().getName()+".selectionTracker",
binding.bolgeListeleyici,
new StableIdKeyProvider(binding.bolgeListeleyici),
new BolgeListelemeAdaptoru.BolgeDetailsLookup(binding.bolgeListeleyici),
StorageStrategy.createLongStorage())
.withSelectionPredicate(SelectionPredicates.createSelectAnything())
.build();
if(savedInstanceState != null) {
st.onRestoreInstanceState(savedInstanceState);
Log.i(TAG, "onViewCreated: hasSelection "+st.hasSelection()+"; count "+st.getSelection().size());
if(st.hasSelection()) {
// Tüm bölgeler yüklenince seçim menüsünü yeniden oluştur
restoreSelection = true;
}
}
st.addObserver(new SelectionTracker.SelectionObserver<Long>() {
#Override
public void onSelectionChanged() {
final int sayim = st.getSelection().size();
Log.i(TAG, "onSelectionChanged: "+sayim+" - "+st.getSelection().toString());
if(sayim > 0) {
if(actionMode == null) {
actionMode = requireActivity().startActionMode(BolgeListeleme.this);
}
actionMode.invalidate();
blvm.mldActionModeBaslik.setValue(sayim+"/"+adaptor.getItemCount());
}
else if(actionMode != null) {
actionMode.finish();
}
}
});
adaptor.selectionTrackerKur(st); // Set up adapter's selectionTracker
blvm = new ViewModelProvider(this).get(BolgeListesiVM.class);
blvm.tumBolgelerLD().observe(getViewLifecycleOwner(), bolgeler -> {
if(bolgeler == null || bolgeler.isEmpty()) {
Log.d(TAG, "Bolgeler null veya boş");
return;
}
adaptor.guncelle(bolgeler);
if(restoreSelection) {
restoreSelection = false;
// Restore and recreate the ActionMode
int sayim = st.getSelection().size();
Log.i(TAG, "onViewCreated: selection "+sayim);
if(sayim > 0) {
if (actionMode == null) {
actionMode = requireActivity().startActionMode(BolgeListeleme.this);
}
blvm.mldActionModeBaslik.setValue(sayim + "/" + adaptor.getItemCount());
}
}
});
binding.fabBolgeEkle.setOnClickListener(v -> bolgeEkle());
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if(st != null) st.onSaveInstanceState(outState);
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
if(actionMode != null) {
actionMode.finish();
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.him_menu_bolgeler, menu);
blvm.mldActionModeBaslik.observe(getViewLifecycleOwner(), mode::setTitle);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
MenuItem miSecim = menu.findItem(R.id.miBolgeTumunuSec);
final int secimSayimi = st.getSelection().size();
final int bolgeSayimi = adaptor.getItemCount();
miSecim.setEnabled(secimSayimi != bolgeSayimi);
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if(item.getItemId() == R.id.miBolgeDuzenle) {
Log.i(TAG, "onActionItemClicked: bölge düzenle");
return true;
}
else if(item.getItemId() == R.id.miBolgeSil) {
int sayim = st.getSelection().size();
String nBolge = getResources().getQuantityString(R.plurals.n_bolge, sayim, sayim);
new MaterialAlertDialogBuilder(requireContext())
.setCancelable(false)
.setTitle(getString(R.string.tc_xSilinecek, nBolge))
.setMessage(getString(R.string.sc_xSilinecek, nBolge))
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.uc_sil, ((dialog, which) -> {
adaptor.secilenleriSil();
snackIletiGoster(getString(R.string.sc_xSilindi, nBolge), 1500);
})).create().show();
return true;
}
else if(item.getItemId() == R.id.miBolgeTumunuSec) {
int secimSayimi = st.getSelection().size();
int bolgeSayimi = adaptor.getItemCount();
if(secimSayimi == bolgeSayimi) {
st.clearSelection();
}
else {
adaptor.tumunuSec();
}
return true;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
blvm.mldActionModeBaslik.removeObservers(getViewLifecycleOwner());
actionMode = null;
st.clearSelection();
}
}
I make whole video player app but stuck at mediacontroller. I want to show my own mediacontroller with different button, not the default one. It's 4rth day, i'm just trying to make my own mediacontroller but didn't succeed.
I succeed by doing it with surfaceview but i want to use it with videoview.
I try the following code.
public class MyMediaController extends MediaController {
private static final String TAG = "VideoControllerView";
MediaController.MediaPlayerControl mPlayer;
private Context mContext;
private View mAnchor;
private View mRoot;
private ProgressBar mProgress;
private TextView mEndTime, mCurrentTime;
private boolean mShowing;
private boolean mDragging;
private static final int sDefaultTimeout = 3000;
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mUseFastForward;
private boolean mFromXml;
private boolean mListenersSet;
StringBuilder mFormatBuilder;
Formatter mFormatter;
private ImageButton mPauseButton;
private ImageButton mSubtitleButton;
private ImageButton mResizeButton;
private ImageButton mNextButton;
private ImageButton mPrevButton;
private final AccessibilityManager mAccessibilityManager;
public MyMediaController(Context context, AttributeSet attrs) {
super(context, attrs);
mRoot = null;
mContext = context;
mUseFastForward = true;
mFromXml = true;
mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
}
public MyMediaController(Context context, boolean useFastForward) {
super(context, useFastForward);
mUseFastForward = useFastForward;
mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
}
public MyMediaController(Context context) {
this(context, true);
mContext = context;
}
#Override
public void setMediaPlayer(MediaController.MediaPlayerControl player) {
mPlayer = player;
updatePausePlay();
}
#Override
public void setAnchorView(View view) {
mAnchor = view;
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
}
protected View makeControllerView() {
LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRoot = inflate.inflate(R.layout.media_controller_layout, null);
initControllerView(mRoot);
return mRoot;
}
private void initControllerView(View mRoot) {
mPauseButton = mRoot.findViewById(R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
}
mResizeButton = mRoot.findViewById(R.id.resize);
if (mResizeButton != null) {
mResizeButton.requestFocus();
mResizeButton.setOnClickListener(mResizeListener);
}
mSubtitleButton = mRoot.findViewById(R.id.subtitle);
if (mSubtitleButton != null)
{
mSubtitleButton.requestFocus();
mSubtitleButton.setOnClickListener(mSubtitleListener);
}
mNextButton = mRoot.findViewById(R.id.next);
if (mNextButton != null ) {
mNextButton.requestFocus();
mNextButton.setOnClickListener(mNextListener);
}
mPrevButton = mRoot.findViewById(R.id.prev);
if (mPrevButton != null ) {
mPrevButton.requestFocus();
mPrevButton.setOnClickListener(mPrevListener);
}
mProgress = mRoot.findViewById(R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mProgress;
seeker.setOnSeekBarChangeListener(mSeekListener);
}
mProgress.setMax(1000);
}
mEndTime = mRoot.findViewById(R.id.time);
mCurrentTime = mRoot.findViewById(R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
}
public final View.OnClickListener mPauseListener = new OnClickListener() {
#Override
public void onClick(View v) {
doPauseResume();
show(sDefaultTimeout);
}
};
private void doPauseResume() {
if (mPlayer == null) {
return;
}
if (mPlayer.isPlaying()) {
mPlayer.pause();
} else {
mPlayer.start();
}
updatePausePlay();
}
private void updatePausePlay() {
if (mRoot == null || mPauseButton == null)
return;
if (mPlayer.isPlaying())
mPauseButton.setImageResource(R.drawable.ic_pause);
else
mPauseButton.setImageResource(R.drawable.ic_play);
}
public final View.OnClickListener mResizeListener = new OnClickListener() {
#Override
public void onClick(View v) {
//Todo
Toast.makeText(mContext,"Resize is clicked",Toast.LENGTH_SHORT).show();
}
};
public final View.OnClickListener mNextListener = new OnClickListener() {
#Override
public void onClick(View v) {
//Todo
Toast.makeText(mContext,"NextBtn is clicked",Toast.LENGTH_SHORT).show();
}
};
public final View.OnClickListener mPrevListener = new OnClickListener() {
#Override
public void onClick(View v) {
//Todo
Toast.makeText(mContext,"PreviousBtn is clicked",Toast.LENGTH_SHORT).show();
}
};
public final View.OnClickListener mSubtitleListener = new OnClickListener() {
#Override
public void onClick(View v) {
//Todo
Toast.makeText(mContext,"subtitleBtn is clicked",Toast.LENGTH_SHORT).show();
}
};
private final SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStartTrackingTouch(SeekBar bar) {
show(3600000);
mDragging = true;
// By removing these pending progress messages we make sure
// that a) we won't update the progress while the user adjusts
// the seekbar and b) once the user is done dragging the thumb
// we will post one of these messages to the queue again and
// this ensures that there will be exactly one message queued up.
removeCallbacks(mShowProgress);
}
#Override
public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
if (!fromuser) {
// We're not interested in programmatically generated changes to
// the progress bar's position.
return;
}
long duration = mPlayer.getDuration();
long newposition = (duration * progress) / 1000L;
mPlayer.seekTo( (int) newposition);
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime( (int) newposition));
}
#Override
public void onStopTrackingTouch(SeekBar bar) {
mDragging = false;
setProgress();
updatePausePlay();
show(sDefaultTimeout);
// Ensure that progress is properly updated in the future,
// the call to show() does not guarantee this because it is a
// no-op if we are already showing.
post(mShowProgress);
}
};
private int setProgress() {
if (mPlayer == null || mDragging) {
return 0;
}
int position = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
if (mProgress != null) {
if (duration > 0) {
// use long to avoid overflow
long pos = 1000L * position / duration;
mProgress.setProgress( (int) pos);
}
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
}
if (mEndTime != null)
mEndTime.setText(stringForTime(duration));
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime(position));
return position;
}
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
private final Runnable mShowProgress = new Runnable() {
#Override
public void run() {
int pos = setProgress();
if (!mDragging && mShowing && mPlayer.isPlaying()) {
postDelayed(mShowProgress, 1000 - (pos % 1000));
}
}
};
#Override
public void show(int timeout) {
if (!mShowing && mAnchor != null) {
setProgress();
if (mPauseButton != null) {
mPauseButton.requestFocus();
}
FrameLayout.LayoutParams tlp = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM
);
addView(this, tlp);
mShowing = true;
}
updatePausePlay();
// cause the progress bar to be updated even if mShowing
// was already true. This happens, for example, if we're
// paused with the progress bar showing the user hits play.
post(mShowProgress);
if (timeout != 0 && !mAccessibilityManager.isTouchExplorationEnabled()) {
removeCallbacks(mFadeOut);
postDelayed(mFadeOut, timeout);
}
}
#Override
public boolean isShowing() {
return mShowing;
}
/**
* Remove the controller from the screen.
*/
#Override
public void hide() {
if (mAnchor == null)
return;
if (mShowing) {
try {
removeCallbacks(mShowProgress);
removeView(this);
} catch (IllegalArgumentException ex) {
Log.w("MediaController", "already removed");
}
mShowing = false;
}
}
private final Runnable mFadeOut = new Runnable() {
#Override
public void run() {
hide();
}
};
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
show(0);
break;
case MotionEvent.ACTION_UP:
show(sDefaultTimeout);
break;
case MotionEvent.ACTION_CANCEL:
hide();
break;
default:
break;
}
return true;
}
}
Plz someone suggest my the right way to do it. I realy need help.
I have a little UI problem with my ViewPager.
My ViewPager is the center of my UI.
I have a NavigationView with 4 items and a Toolbar with 2 items.
Each time an item of the NavigationView is clicked, I replace the adapter. Therefore I have 4 adapters and only one is causing problems : BrowseAdapter (code is below).
This adapter is filled with a list of Events and provide a Fragment for each Event.
Something good to know is that whatever the size of the eventList is, the setAdapter method of the ViewPager takes at least 150ms to execute, whereas for the other Adapters, it takes only 20 to 50ms to load.
I have tried to put all calls to setAdapter in the View.post(new Runnable()); method and in an AsyncTask<Void, Void, Void> :
The post method froze the UI
The AsyncTask changed nothing because I can only call setAdapter on the UI Thread (in the postExecute method) which is basically the same as calling it without the AsyncTask.
I think this is basically an optimization problem but I can't see where is the problem.
Thank you for you help.
Here is the code in question :
MainActivity :
/*
.
. Import stuff
.
.
.*/
public class MainActivity extends AppCompatActivity implements RequestCallback,
ConnectionCallbacks, OnConnectionFailedListener, FBLoginChanged, LocationListener {
/**
* The main content view
*/
private CustomViewPager mViewPager;
/**
* Adapters : One for each feature of the application
*/
private BrowseAdapter mBrowseAdapter;
private CurrentAdapter mCurrentAdapter = new CurrentAdapter(getFragmentManager());
private CalendarAdapter mCalendarAdapter = new CalendarAdapter(getFragmentManager());
private SettingsAdapter mSettingsAdapter = new SettingsAdapter(getFragmentManager());
/**
* The action bar of the application
*/
private Toolbar mToolbar;
/**
* TabLayout provide the new Material Design tab navigation
*/
private TabLayout mTabLayout;
/**
* Side navigation given by a NavigationView instead of a NavigationDrawer
* to support Material Design
*/
private NavigationView mNavigationView;
private DrawerLayout mDrawerLayout;
/**
* List of all events.
*/
private ArrayList<Event> mEventList = new ArrayList<Event>();
/**
* Provide different way of browsing through the events
*/
private enum BrowseType {
DEFAULT,
POPULAR,
RANDOM
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*.
.
. Initialization stuff
.
.*/
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Closing drawer on item click
mDrawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()){
case R.id.home:
mTabLayout.setVisibility(View.VISIBLE);
mBrowseAdapter.setBrowsingType(BrowseType.DEFAULT);
mViewPager.setAdapter(mBrowseAdapter);
break;
case R.id.favs:
mTabLayout.setVisibility(View.GONE);
mViewPager.setAdapter(mCurrentAdapter);
break;
case R.id.calendar:
mTabLayout.setVisibility(View.GONE);
mViewPager.setAdapter(mCalendarAdapter);
break;
case R.id.setting:
mTabLayout.setVisibility(View.GONE);
mViewPager.setAdapter(mSettingsAdapter);
break;
default:
break;
}
return true;
}
});
mViewPager = (CustomViewPager) findViewById(R.id.pager);
mBrowseAdapter = new BrowseAdapter(this.getFragmentManager(), mEventList);
mTabLayout.setOnTabSelectedListener(new OnTabSelectedListener() {
#Override
// Unused
public void onTabReselected(Tab tab) {
}
#Override
public void onTabSelected(Tab tab) {
switch(tab.getPosition()) {
case 0:
mBrowseAdapter.setBrowsingType(BrowseType.DEFAULT);
break;
case 1:
mBrowseAdapter.setBrowsingType(BrowseType.POPULAR);
break;
default: // Unused
break;
}
mViewPager.setAdapter(mBrowseAdapter);
}
#Override
// Unused
public void onTabUnselected(Tab tab) {
}
});
mViewPager.setAdapter(mBrowseAdapter);
}
}
My adapter :
private class BrowseAdapter extends FragmentStatePagerAdapter {
private ArrayList<Event> eventList = new ArrayList<Event>();
private BrowseType browseType = BrowseType.DEFAULT;
private HashMap<Integer, EventFragment> fragmentReferenceMap = new HashMap<Integer, EventFragment>();
public BrowseAdapter(FragmentManager fragmentManager,
ArrayList<Event> mEventList) {
super(fragmentManager);
}
public void setBrowsingType(BrowseType type) {
this.browseType = type;
this.commitChanges();
}
public Event getEventById(int id) {
for(Event event : eventList) {
if(event.getId() == id)
return event;
}
return null;
}
public void setJSONData(JSONArray jsonArray) {
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject obj = jsonArray.getJSONObject(i);
Event event = new Event();
event.setId(obj.getInt("id"));
event.setName(obj.getString("name"));
event.setShort_description(obj.getString("short_desc"));
event.setLong_description(obj.getString("long_desc"));
event.setPlace(obj.getString("place").split(";")[0]);
Location loc = new Location("");
loc.setLatitude(Double.valueOf(obj.getString("place")
.split(";")[1]));
loc.setLongitude(Double.valueOf(obj.getString("place")
.split(";")[2]));
event.setLocation(loc);
event.setDate(obj.getString("date"));
eventList.add(event);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
public String getJSONData() {
JSONArray toReturn = new JSONArray();
for (Event event : eventList) {
JSONObject tmp = new JSONObject();
try {
tmp.put("name", event.getName());
tmp.put("short_desc", event.getShort_description());
tmp.put("long_desc", event.getLong_description());
tmp.put("id", event.getId());
tmp.put("date", event.getDate());
tmp.put("place",
event.getPlace()
+ ";"
+ String.valueOf(event.getLocation()
.getLatitude())
+ ";"
+ String.valueOf(event.getLocation()
.getLongitude()));
toReturn.put(tmp);
} catch (JSONException e) {
e.printStackTrace();
}
}
return toReturn.toString();
}
public boolean addItem(Event item) {
return eventList.add(item);
}
#SuppressWarnings("unused")
public Event removeAt(int position) {
return eventList.remove(position);
}
public void commitChanges() {
this.sort();
this.notifyDataSetChanged();
}
private void sort() {
Log.d("SORT", browseType.name());
Collections.sort(eventList, new Comparator<Event>() {
#Override
public int compare(Event arg0, Event arg1) {
float dis1 = arg0.getLocation().distanceTo(
LocationProvidor.getInstance().getLastLocation());
float dis2 = arg1.getLocation().distanceTo(
LocationProvidor.getInstance().getLastLocation());
int userNumber1 = Integer.parseInt(arg0.getUserNumber());
int userNumber2 = Integer.parseInt(arg1.getUserNumber());
switch(browseType) {
case DEFAULT:
return (int) (dis1 - dis2);
case POPULAR:
return userNumber2 - userNumber1;
case RANDOM:
return new Random().nextInt();
default:
return 0;
}
}
});
}
public void empty() {
eventList.clear();
}
#Override
public EventFragment getItem(int position) {
EventFragment frag = EventFragment.newInstance(eventList.get(position));
frag.setIsCurrents(mCurrentAdapter.containsEventId(eventList.get(position).getId()));
fragmentReferenceMap.put(position, frag);
return frag;
}
#Override
public void destroyItem(View container, int position, Object object) {
super.destroyItem(container, position, object);
fragmentReferenceMap.remove(position);
Log.d("fr.blopper.app", "destroy " + position);
}
public EventFragment getFragment(int position) {
return fragmentReferenceMap.get(position);
}
#Override
public int getCount() {
return eventList.size();
}
}
And CustomViewPager (I have created it only to measure the time taken by setAdapter):
import android.content.Context;
import android.util.AttributeSet;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.support.v4.view.PagerAdapter;
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context c) {
super(c);
}
public CustomViewPager(Context c, AttributeSet as) {
super(c, as);
}
#Override
public void setAdapter(PagerAdapter adapter) {
long start = System.currentTimeMillis();
super.setAdapter(adapter);
Log.d("TAG", "Custom time " + (System.currentTimeMillis() - start));
}
}
Found the answer, it has nothing to do with the ViewPager.
The Fragments provided by the Adapter were making a call to a Google API which was slow to answer.
I am using OpenCV for android and i am trying to set a custom frame rate. Well right now i am trying to set the range for frame rate. I am also trying to set the custom resolution
I am following the openCV tutorial 3 Camera Control. the app is crashing as i start running it on my device. I am using Nexus 7 2013 tablet
Following is my code:
public class Tutorial2Activity extends Activity implements CvCameraViewListener2
{
private static final String TAG = "OCVSample::Activity";
private static final int VIEW_MODE_RGBA = 0;
private static final int VIEW_MODE_GRAY = 1;
private static final int VIEW_MODE_CANNY = 2;
private static final int VIEW_MODE_FEATURES = 5;
private int mViewMode;
private Mat mRgba;
private Mat mIntermediateMat;
private Mat mGray;
private MenuItem mItemPreviewRGBA;
private MenuItem mItemPreviewGray;
private MenuItem mItemPreviewCanny;
private MenuItem mItemPreviewFeatures;
private CustomizeCameraView mOpenCvCameraView;
private List<Size> mResolutionList;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
// Load native library after(!) OpenCV initialization
System.loadLibrary("mixed_sample");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public Tutorial2Activity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.tutorial2_surface_view);
mOpenCvCameraView = (CustomizeCameraView) findViewById(R.id.tutorial2_activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i(TAG, "called onCreateOptionsMenu");
mItemPreviewRGBA = menu.add("Preview RGBA");
mItemPreviewGray = menu.add("Preview GRAY");
mItemPreviewCanny = menu.add("Canny");
mItemPreviewFeatures = menu.add("Find features");
return true;
}
#Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
#Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
mGray = new Mat(height, width, CvType.CV_8UC1);
mResolutionList = mOpenCvCameraView.getResolutionList();
int mFrameWidth = (int) mResolutionList.get(7).width;
int mFrameHeight = (int) mResolutionList.get(7).height;
mOpenCvCameraView.setResolution(mFrameHeight,mFrameWidth);
//mOpenCvCameraView.setPreviewFPS(1000, 31000);
}
public void onCameraViewStopped() {
mRgba.release();
mGray.release();
mIntermediateMat.release();
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return inputFrame.rgba();
}
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
if (item == mItemPreviewRGBA) {
mViewMode = VIEW_MODE_RGBA;
} else if (item == mItemPreviewGray) {
mViewMode = VIEW_MODE_GRAY;
} else if (item == mItemPreviewCanny) {
mViewMode = VIEW_MODE_CANNY;
} else if (item == mItemPreviewFeatures) {
mViewMode = VIEW_MODE_FEATURES;
}
return true;
}
public native void FindFeatures(long matAddrGr, long matAddrRgba);
}
And the JavaCameraView custom class
public class CustomizeCameraView extends JavaCameraView{
public CustomizeCameraView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//#SuppressWarnings("deprecation")
public void setPreviewFPS(double min, double max){
Camera.Parameters params = mCamera.getParameters();
params.setPreviewFpsRange((int)(min*1000), (int)(max*1000));
//params.setPreviewFrameRate(min);
mCamera.setParameters(params);
// mCamera.getSupportedPreviewFpsRange();
}
public List<Size> getResolutionList() {
return mCamera.getParameters().getSupportedPreviewSizes();
// return mCamera.getParameters().getPictureSize();
}
public void setResolution(int h,int w){
Camera.Parameters params = mCamera.getParameters();
params.setPreviewSize(mFrameWidth, mFrameHeight);
mCamera.setParameters(params); // mCamera is a Camera object
}
public Size getResolution() {
return mCamera.getParameters().getPreviewSize();
}
}
and the logcat output is as follows:
05-23 14:27:18.192: E/AndroidRuntime(29339): FATAL EXCEPTION: main
05-23 14:27:18.192: E/AndroidRuntime(29339): Process: org.opencv.samples.tutorial2, PID: 29339
05-23 14:27:18.192: E/AndroidRuntime(29339): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.opencv.samples.tutorial2/org.opencv.samples.tutorial2.Tutorial2Activity}: java.lang.ClassCastException: org.opencv.android.JavaCameraView cannot be cast to org.opencv.samples.tutorial2.CustomizeCameraView
I found the solution
the problem was with my layout file. i inserted the tag for video display for directly usage of JavaCameraView instead of using the inherited class from JavaCameraView
problem:
< org.opencv.JavaCameraView />
corrected:
< "package_name"."Class_name_that_you_inherited_from_JavaCameraView" />
i hope it helps others :)
I don't know how to custom my own Fragment which inherite another Fragment class.
I'd like to add button and catch every click on them, but I don't how to do that.
As you'll see, I'm using actionBarSherlock and Zxing (a sub-library of Zxing actually: "barcodeFragLibV2") and the navigation drawer.
Here my code:
MainActivity.java:
public class MainActivity extends SherlockFragmentActivity {
private static final String TAG = MainActivity.class.getSimpleName();
/**
* The navigation drawer layout.
*/
DrawerLayout mDrawerLayout;
/**
* The elements list of the menu.
*/
ListView mDrawerList;
/**
* The button to open/close the menu.
*/
ActionBarDrawerToggle mDrawerToggle;
/**
* The helper item of the local database.
*/
private DatabaseHelper dbHelper = null;
/**
* The current fragment title.
*/
String mTitle = "";
/**
* #author LG
* #category Property
*/
private boolean mShowOptionMenu;
private int fragmentStatus = 0;
private Menu mMenu = null;
private MenuItem mGoItem;
private static final int GO_ITEM_ID = 1;
private static final int CLEAR_ITEM_ID = 2;
public String getmTitle() {
return mTitle;
}
public void setmTitle(String mTitle) {
this.mTitle = mTitle;
}
/**
* Method called when the activity is loaded.
*
* #param savedInstanceState
* the bundle sent.
*/
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "================= onCreate =================");
if (!isTablet()) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
setContentView(R.layout.activity_main);
mTitle = (String) getTitle();
mShowOptionMenu = false;
// result_view = findViewById(R.id.result_view);
// result_view.setVisibility(View.GONE);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.drawer_list);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
/** Called when drawer is closed */
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(mTitle);
invalidateOptionsMenu();
}
/** Called when a drawer is opened */
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle("Menu");
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
MenuListAdapter adapter = new MenuListAdapter(getBaseContext());
mDrawerList.setAdapter(adapter);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true);
displayView(position);
}
private void displayView(int position) {
String[] menu = getResources().getStringArray(R.array.menu);
mTitle = menu[position];
MainActivity.this.fragmentStatus = position;
SherlockFragment rFragment = null;
Log.d(TAG, "================= mDrawerList.setOnItemClickListener =================");
if (position == 0)
rFragment = new SearchFragment();
else if (position == 1) {
mShowOptionMenu = true;
rFragment = new AdvanceSearchFragment();
} else if (position == 2) {
rFragment = new QrCodeScannerFragment(); // WORKS
} else if (position == 3)
rFragment = new FavorisFragment();
else if (position == 4)
rFragment = new HistoriqueFragment();
else if (position == 5)
rFragment = new InformationsFragment();
if (rFragment != null) {
Bundle data = new Bundle();
data.putInt("position", position);
rFragment.setArguments(data);
FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() > 0)
fragmentManager.popBackStackImmediate();
FragmentTransaction ft = fragmentManager.beginTransaction();
// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.replace(R.id.content_frame, rFragment);
ft.addToBackStack(null);
ft.commit();
mDrawerLayout.closeDrawer(mDrawerList);
}
}
}
);
SearchFragment rFragment = new SearchFragment();
Bundle data = new Bundle();
rFragment.setArguments(data);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, rFragment);
ft.commit();
}
/**
* Method called after the activity is loaded.
*
* #param savedInstanceState
* the bundle sent.
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
Log.d(TAG, "================= onPostCreate =================");
mDrawerToggle.syncState();
}
/**
* Inflate the menu; this adds items to the action bar if it is present.
*
* #param menu
* the menu
*/
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(TAG, "================= onCreateOptionsMenu ================= fragSt: " + fragmentStatus);
getSupportMenuInflater().inflate(R.menu.main, (Menu) menu);
if (fragmentStatus == 1) {
Log.i(TAG, "Show optionMenu");
mGoItem = menu.add(0, GO_ITEM_ID, 0, null);
mGoItem.setIcon(R.drawable.abs__ic_go).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
mShowOptionMenu = false;
}
return true;
}
/**
* Called whenever we call invalidateOptionsMenu()
*
* #param menu
* the menu
*/
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the drawer is open, hide action items related to the content view
Log.d(TAG, "================= onPrepareOptionsMenu ================= fragSt: " + fragmentStatus);
return super.onPrepareOptionsMenu(menu);
}
/**
* Method called when an menu's item is selected.
*
* #param item
* the item selected
*/
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "================= onOptionsItemSelected ================= fragSt: " + fragmentStatus);
switch (item.getItemId()) {
case android.R.id.home:
if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
mDrawerLayout.closeDrawer(mDrawerList);
} else {
mDrawerLayout.openDrawer(mDrawerList);
}
return true;
}
return false;
}
/**
* Method to get device button actions
*
* #param keyCode
* the code of the button pressed
* #param event
* the event
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.d(TAG, "================= onKeyDown ================= fragSt: " + fragmentStatus);
Log.w(TAG, "KeyEven: " + keyCode);
if (keyCode == KeyEvent.KEYCODE_MENU ) {
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
if (!drawerOpen)
mDrawerLayout.openDrawer(Gravity.LEFT);
else
mDrawerLayout.closeDrawer(Gravity.LEFT);
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
Log.d(TAG, "TouchKeyBack");
}
return super.onKeyDown(keyCode, event);
}
/**
* Method called when the back button is pressed
*/
#Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (mShowOptionMenu == true)
mShowOptionMenu = false;
Log.d(TAG, "onBackPressed");
int tt = fm.getBackStackEntryCount();
// Log.d(TAG, "BackStackEntry name : " +
// fm.getBackStackEntryAt(tt).getName());
if (fm.getBackStackEntryCount() > 0) {
Log.i("MainActivity", "popping backstack");
getSupportFragmentManager().popBackStack();
} else {
Log.i("MainActivity", "nothing on backstack, calling super");
super.onBackPressed();
}
}
/**
* Method to know if the device is tablet or smartphone
*
* #return a boolean indicating if the device is a tablet
*/
public boolean isTablet() {
Log.d(TAG, "================= isTablet =================");
boolean xlarge = ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == 4);
boolean large = ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE);
return (xlarge || large);
}
/**
* Method called when the activity is deallocated
*/
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "================= onDestroy =================");
if (dbHelper != null) {
OpenHelperManager.releaseHelper();
dbHelper = null;
}
}
/**
* Return the database helper
*/
public DatabaseHelper getHelper() {
if (dbHelper == null) {
dbHelper = (DatabaseHelper) OpenHelperManager.getHelper(this, DatabaseHelper.class);
}
return dbHelper;
}
/**
* Method called when the activity start. Used for Google Analytics
*/
#Override
public void onStart() {
super.onStart();
Log.d(TAG, "================= onStart =================");
EasyTracker.getInstance(this).activityStart(this);
}
/**
* Method called when the activity stop. Used for Google Analytics
*/
#Override
public void onStop() {
Log.d(TAG, "================= onStop =================");
super.onStop();
EasyTracker.getInstance(this).activityStop(this);
}
}
QrCodeScannerFragment.java:
public class QrCodeScannerFragment extends BarcodeFragment {
public static final String TAG = QrCodeScannerFragment.class.getSimpleName();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setScanResultHandler(new IScanResultHandler() {
#Override
public void scanResult(ScanResult result) {
Log.w(TAG, "ScanResult");
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
return super.onCreateView(inflater, container, savedInstanceState);
}
}
BarcodeFragment.java:
public class BarcodeFragment extends SherlockFragment implements SurfaceHolder.Callback {
private static final String TAG = BarcodeFragment.class.getSimpleName();
private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;
private CameraManager cameraManager;
private CaptureFragmentHandler handler;
private Result savedResultToShow;
private ViewfinderView viewfinderView;
private boolean hasSurface;
private Collection<BarcodeFormat> decodeFormats;
private Map<DecodeHintType, ?> decodeHints;
private String characterSet;
private InactivityTimer inactivityTimer;
private AmbientLightManager ambientLightManager;
private IScanResultHandler resultHandler;
public ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return handler;
}
public CameraManager getCameraManager() {
return cameraManager;
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
hasSurface = false;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FrameLayout frameLayout = new FrameLayout(getActivity());
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
frameLayout.setLayoutParams(layoutParams);
surfaceView = new SurfaceView(getActivity());
surfaceView.setLayoutParams(layoutParams);
viewfinderView = new ViewfinderView(getActivity());
viewfinderView.setLayoutParams(layoutParams);
frameLayout.addView(surfaceView);
frameLayout.addView(viewfinderView);
View v = frameLayout;
inactivityTimer = new InactivityTimer(this.getActivity());
ambientLightManager = new AmbientLightManager(this.getActivity());
return v;
}
SurfaceView surfaceView;
#SuppressWarnings("deprecation")
#Override
public void onResume() {
super.onResume();
// CameraManager must be initialized here, not in onCreate(). This is
// necessary because we don't
// want to open the camera driver and measure the screen size if we're
// going to show the help on
// first launch. That led to bugs where the scanning rectangle was the
// wrong size and partially
// off screen.
cameraManager = new CameraManager(this.getActivity(), getView());
viewfinderView.setCameraManager(cameraManager);
handler = null;
resetStatusView();
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
// The activity was paused but not stopped, so the surface still
// exists. Therefore
// surfaceCreated() won't be called, so init the camera here.
initCamera(surfaceHolder);
} else {
// Install the callback and wait for surfaceCreated() to init the
// camera.
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
ambientLightManager.start(cameraManager);
inactivityTimer.onResume();
decodeFormats = null;
characterSet = null;
}
#Override
public void onPause() {
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
inactivityTimer.onPause();
ambientLightManager.stop();
cameraManager.closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = this.surfaceView;
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
#Override
public void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
public void restart() {
restartPreviewAfterDelay(BULK_MODE_SCAN_DELAY_MS);
}
private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
// Bitmap isn't used yet -- will be used soon
if (handler == null) {
savedResultToShow = result;
} else {
if (result != null) {
savedResultToShow = result;
}
if (savedResultToShow != null) {
Message message = Message.obtain(handler, IDS.id.decode_succeeded, savedResultToShow);
handler.sendMessage(message);
}
savedResultToShow = null;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
}
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
/**
* A valid barcode has been found, so give an indication of success and show
* the results.
*
* #param rawResult
* The contents of the barcode.
* #param scaleFactor
* amount by which thumbnail was scaled
* #param barcode
* A greyscale bitmap of the camera data which was decoded.
*/
public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
inactivityTimer.onActivity();
ScanResult resultHandler = ResultHandlerFactory.parseResult(rawResult);
boolean fromLiveScan = barcode != null;
if (fromLiveScan) {
drawResultPoints(barcode, scaleFactor, rawResult);
}
handleDecodeInternally(rawResult, resultHandler, barcode);
}
/**
* Superimpose a line for 1D or dots for 2D to highlight the key features of
* the barcode.
*
* #param barcode
* A bitmap of the captured image.
* #param scaleFactor
* amount by which thumbnail was scaled
* #param rawResult
* The decoded results which contains the points to draw.
*/
private void drawResultPoints(Bitmap barcode, float scaleFactor, Result rawResult) {
ResultPoint[] points = rawResult.getResultPoints();
if (points != null && points.length > 0) {
Canvas canvas = new Canvas(barcode);
Paint paint = new Paint();
paint.setColor(Color.parseColor("#c099cc00"));
if (points.length == 2) {
paint.setStrokeWidth(4.0f);
drawLine(canvas, paint, points[0], points[1], scaleFactor);
} else if (points.length == 4
&& (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A || rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
// Hacky special case -- draw two lines, for the barcode and
// metadata
drawLine(canvas, paint, points[0], points[1], scaleFactor);
drawLine(canvas, paint, points[2], points[3], scaleFactor);
} else {
paint.setStrokeWidth(10.0f);
for (ResultPoint point : points) {
canvas.drawPoint(scaleFactor * point.getX(), scaleFactor * point.getY(), paint);
}
}
}
}
private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, float scaleFactor) {
if (a != null && b != null) {
canvas.drawLine(scaleFactor * a.getX(), scaleFactor * a.getY(), scaleFactor * b.getX(), scaleFactor * b.getY(), paint);
}
}
// Put up our own UI for how to handle the decoded contents.
private void handleDecodeInternally(Result rawResult, ScanResult resultHandler, Bitmap barcode) {
viewfinderView.setVisibility(View.GONE);
if (this.resultHandler != null) {
this.resultHandler.scanResult(resultHandler);
}
}
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
return;
}
try {
cameraManager.openDriver(surfaceHolder);
// Creating the handler starts the preview, which can also throw a
// RuntimeException.
if (handler == null) {
handler = new CaptureFragmentHandler(this, decodeFormats, decodeHints, characterSet, cameraManager);
}
decodeOrStoreSavedBitmap(null, null);
} catch (IOException ioe) {
Log.w(TAG, ioe);
displayFrameworkBugMessageAndExit();
} catch (RuntimeException e) {
// Barcode Scanner has seen crashes in the wild of this variety:
// java.?lang.?RuntimeException: Fail to connect to camera service
Log.w(TAG, "Unexpected error initializing camera", e);
displayFrameworkBugMessageAndExit();
}
}
private void displayFrameworkBugMessageAndExit() {
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
builder.setTitle(getString(R.string.app_name));
builder.setMessage("Sorry, the Android camera encountered a problem. You may need to restart the device.");
builder.setPositiveButton("OK", new FinishListener(this.getActivity()));
builder.setOnCancelListener(new FinishListener(this.getActivity()));
builder.show();
}
public void restartPreviewAfterDelay(long delayMS) {
if (handler != null) {
handler.sendEmptyMessageDelayed(IDS.id.restart_preview, delayMS);
}
resetStatusView();
}
private void resetStatusView() {
viewfinderView.setVisibility(View.VISIBLE);
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
public IScanResultHandler getScanResultHandler() {
return resultHandler;
}
public void setScanResultHandler(IScanResultHandler resultHandler) {
this.resultHandler = resultHandler;
}
}