I am using the VerticalGridFragment from the git sample to just display information and do not want user interaction. I successfully turned off the user focusing in the CardPresenter.cs but I would also like to change all the cards so they are not dim.
Here is a screenshot of the class and the dimming I would like to turn off. http://corochann.com/verticalgridfragment-android-tv-application-hands-on-tutorial-19-718.html
I have tried changing the alpha inside of the CardPresenter class but this does not seem to do anything. Any help would be appreciated!
CardPresenter.cs
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
mDefaultBackgroundColor =
ContextCompat.getColor(parent.getContext(), R.color.default_background);
mSelectedBackgroundColor =
ContextCompat.getColor(parent.getContext(), R.color.selected_background);
mDefaultCardImage = parent.getResources().getDrawable(R.drawable.movie, null);
ImageCardView cardView = new ImageCardView(parent.getContext()) {
#Override
public void setSelected(boolean selected) {
updateCardBackgroundColor(this, selected);
super.setSelected(selected);
}
};
cardView.setAlpha(1.0f);
cardView.setFocusable(false);
cardView.setFocusableInTouchMode(false);
updateCardBackgroundColor(cardView, false);
return new ViewHolder(cardView);
}
create your presenter like so:
VerticalGridPresenter gridPresenter = new VerticalGridPresenter(FocusHighlight.ZOOM_FACTOR_LARGE,false);
the "false" is for enable / disable dimming
You may want to start using these helper classes that are primarily used for applying dim level or color to your View.
ColorOverlayDimmer
Helper class for assigning a dim color to Paint. It holds the alpha value for the current active level.
ColorFilterDimmer
Helper class for applying a dim level to a View. The ColorFilterDimmer uses a ColorFilter in a Paint object to dim the view according to the currently active level.
Sample implementation codes in Java can be found here. Hope it helps!
Related
I've built a custom cast sender in my app that works perfectly - the only feature I need to add is a way to listen for the 'Play/Pause' and 'Skip' buttons, but Google's documentation (as far as I've been able to search for) doesn't give any clues, and after adding the functionality shown in Advanced Cast Features Docs did not work:
CastMediaOptions castMediaOptions = new CastMediaOptions.Builder()
.setMediaIntentReceiverClassName(CastIntentReceiver.class.getName())
.build();
return new CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.cast_id))
.setCastMediaOptions(castMediaOptions)
.build();
I have a CastIntentReceiver that extends MediaIntentReceiver that's referenced in CastOptionsProvider and in the manifest.
public class CastIntentReceiver extends MediaIntentReceiver {
public static String TAG = "CastIntentReceiver";
public CastIntentReceiver() {
Log.i(TAG, "CastIntentReceiver: Constructed!");
}
...
// The rest of the Override methods don't do anything
}
The receiver is working, because the Log print is working, but none of the Override methods are called (no Log printing).
Here are some additional details on my implementation:
All casting functions are in two separate classes, the CastManager (controller) and the CastControls fragment (view) which is added to the base of the MainActivity View (similar to YouTube). There are also Interfaces that trigger things between these two classes.
In the CastManager, I setup the UIMediaController and bind Views:
View view = CastingBridge.CAST_CONTROLS_VIEW.findViewById(R.id.cast_drawer_controls);
uiMediaController = new UIMediaController(activity);
SeekBar seekBar = (SeekBar) view.findViewById(R.id.cast_control_seek_bar);
TextView start = (TextView) view.findViewById(R.id.cast_control_time_start);
TextView end = (TextView) view.findViewById(R.id.cast_control_time_end);
ImageButton playPauseButton = (ImageButton) view.findViewById(R.id.cast_control_play_pause);
ImageButton rewindButton = (ImageButton) view.findViewById(R.id.cast_control_rewind);
ImageButton forwardButton = (ImageButton) view.findViewById(R.id.cast_control_forward);
ImageButton stopButton = (ImageButton) view.findViewById(R.id.cast_control_stop);
ProgressBar loadingSpinner = (ProgressBar) view.findViewById(R.id.cast_control_loading);
As stated before, all these work as they should, but I need to listen for (capture) the touch/click events so that when a video is paused or stopped, I can save the current watch length for resume purposes.
How do I implement MediaIntentReceiver to listen for these events? I've tried adding click listeners to the individual Views, but as expected, #Override onClick removes the initial intended functionality.
The documentation specifies what seem to be the methods I need, but how is this referenced?
I also tried adding the only listener available to UIMediaController:
uiMediaController.setPostRemoteMediaClientListener(new RemoteMediaClient.Listener() {
#Override
public void onStatusUpdated() {
Log.i(TAG, "onStatusUpdated: Status Updated");
}
});
This, however does not do anything, as the onStatusUpdated method supplies no arguments.
Can anyone help me shed some light onto this? I've been trying different things and searching for a couple days now, so time to ask for help.
Thanks!
The receiver you have defined (and MediaIntentReceiver in general) is used to handle actions from notification, lockscreen and cast dialog; so having a custom one affects the behavior when it is initiated from those places. If you are using UIMediaController, then you'd need to use onSendingRemoteMediaRequest() to be notified when user interacts with these controls.
Why links in ListView are lost, when scrolling? From debugging it's clear, that spans are not added second time on a TextView from the convertView.
Here's a piece of code which is called from adapter's getView.
...
String body = MyItemDetails.getBody(); // String to linkify
final Spannable spannable = MyCustomUri.addHashtagSpans(context, body);
viewHolder.textView.setText(spannable);
viewHolder.textView.setTextIsSelectable(true); // adds additional spans
viewHolder.textView.setMovementMethod(ArrowKeyMovementMethod.getInstance());
viewHolder.textView.setAutoLinkMask(Linkify.WEB_URLS);
...
MyCustomUri.addHashtagSpans() creates a SpannableString with MyCustomSpan with extends URLSpan.
Problem is that when I scroll up and down in the ListView links are lost. Whereas when screen is opened 1st time it's set correctly.
Now I made a dirty fix by disabling reuse of convertView :( Any ideas how to solve this problem better?
Some of the spannable information is likely being lost when the textview's data is written to a parcel for retention.
See TextView.onSaveInstanceState(), TextView.onRestoreInstanceState(), and TextView.SavedState.
It can often be very frustrating to determine what android will and will not retain. I often just setSaveEnabled(false) on my views to disable the unpredictable default behaviours of the base widgets.
Also, the viewholder pattern is only really intended for retaining view/layout instance hierarchies. To save you from having to inflate or find your views every getView(). It's always your responsibility to update a view's data when presenting it from getView().
You don't need to completely disable the viewholder pattern, instead just simply update the text every getView(), as you may already be doing.
Hello Use this custom class
public class MyCustomSpannable extends ClickableSpan {
String Url;
Context mContext;
public MyCustomSpannable(String Url, Context context) {
this.Url = Url;
mContext = context;
}
#Override
public void updateDrawState(TextPaint ds) {
// Customize your Text Look if required
ds.setColor(mContext.getResources().getColor(R.color.red_text));
ds.setFakeBoldText(true);
// ds.setStrikeThruText(true);
ds.setTypeface(CommonFunctios.getfontNormal(mContext));
// ds.setUnderlineText(true);
// ds.setShadowLayer(10, 1, 1, Color.WHITE);
// ds.setTextSize(15);
}
#Override
public void onClick(View widget) {
}
public String getUrl() {
return Url;
}
}
and in adapter replace your code with this
String text = holder.txt_terms.getText().toString();
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text);
MyCustomSpannable customSpannable = new MyCustomSpannable(text,
mcontext) {
#Override
public void onClick(View widget) {
Log.e("on click", "message");
((OpticalOffersActivity) mcontext).callDialogBox(position);
}
};
stringBuilder.setSpan(customSpannable, 0, text.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
holder.txt_terms.setText(stringBuilder, BufferType.SPANNABLE.SPANNABLE);
holder.txt_terms.setMovementMethod(LinkMovementMethod.getInstance());
Hope it will help you.
if(convertView==null)
{
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
...
String body = MyItemDetails.getBody(); // String to linkify
final Spannable spannable = MyCustomUri.addHashtagSpans(context, body);
viewHolder.textView.setText(spannable);
viewHolder.textView.setTextIsSelectable(true); // adds additional spans
viewHolder.textView.setMovementMethod(ArrowKeyMovementMethod.getInstance());
viewHolder.textView.setAutoLinkMask(Linkify.WEB_URLS);
...
That spannable code must be placed outside the if-else loop in the getView() method, like the way I did it in the above code.
There are a couple problems at play here, so let me address them one at a time. The issues you've asked about directly (links disappearing) is a side effect of the fact that the auto linking behavior in TextView doesn't necessarily work that well when you are also adding your own spans to the text manually...best not to use it. Remove the setAutoLinkMask() trigger and the disappearing links issue will go away.
Instead, you can easily add the same web linking behavior directly into your text span with Linkify. However, this is only part of your problem. The MovementMethod you have chosen isn't really compatible with clickable links. The reason it (partially) works in your code now is because the auto link mask is causing the MovementMethod of the view to be secretly massaged under the hood to a LinkMovementMethod...which then gets reset after the view is recycled. A pattern I typically use (applied to your code example) would be:
final Spannable spannable = MyCustomUri.addHashtagSpans(context, body);
Linkify.addLinks(spannable, Linkify.WEB_URLS);
viewHolder.textView.setText(spannable);
addLinkMovementMethod(textView);
Where addLinkMovementMethod() is a helper I have that looks like this:
private void addLinkMovementMethod(TextView t) {
MovementMethod m = t.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (t.getLinksClickable()) {
t.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
This simply keeps from resetting the value on each view recycle if it isn't necessary. The previous code block will give you links that click properly and never disappear...
However, I'm guessing from the methods you've called that you are also attempting to make the linked text in the list selectable (e.g. calling setTextIsSelectable() and choosing the ArrowKeyMovementMethod). This gets a little trickier because of the MovementMethod issue I discussed above. In order to create a MovementMethod that supports both link clicks and text selection, I'll direct you to this existing SO post on the subject which includes sample code on the customizations you need to make: Can a TextView be selectable AND contain links?
I am developing in android and i have a requirement for making a custom ui picker view like the one in iphone for which i am using the code from the link
http://code.google.com/p/scroll-picker-view-for-android/
here in the
scrollPickerViewListener = this;
scrollPickerView = new ScrollPickerView(this);
scrollPickerView.addSlot(getResources().getStringArray(R.array.custom_list), 1, ScrollPickerView.ScrollType.Ranged);
scrollPickerView.setSlotIndex(0, 13);
ViewGroup.LayoutParams params = new
ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, 200);
this.setContentView(scrollPickerView, params);
how to get the index of the selected item from the pickerview when the user scrolls
I would first ask why you would want to create an iPhone picker instead of using ones made for Android, anyways...
I checked some of the source code of the library you are using and it seems that the developer of this library thought it was funny to leave absolutely no comments behind. It extends from a ListView so it shouldn't be that hard.
A quick glance shows a ScrollPickerViewListener. You should probably use that. Try this.
scrollPickerView.setScrollPickerViewListener(){
public void onSingleTapUp(int index){
}
}
Or...
#Override
public void onSingleTapUp(int slotId) {
Toast.makeText(this, ""+slotId, Toast.LENGTH_SHORT).show();
}
Is it possible to get a list of all Windows in my Android app?
If not, is it possible to get notifications on creation of a new View or a Window?
Cheers :)
For example: I would like to know if there's a visible keyboard view on the screen, or if there's an alert dialog on screen. Is that possible? Can I get the View or Window instance holding it?
Yes this is possible in a number of different ways. All views being displayed on the screen are added to a ViewGroup, which are usually layouts such as R.layout.main, LinearLayout, RelativeLayout, etc.
You can access the views at runtime, after the layouts have been built, using a handler such as onWindowFocusChanged:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
int count = myLayout.getChildCount();
for(int i = 0; i < count; i++)
{
View v = myLayout.getChildAt(i);
...
}
}
You can simply set up a thread inside onWindowFocusChanged that would notify you if a keyboard is created by constantly checking the number of children views of the current layout.
For the keyboard issue, you can use your own keyboard view instance with KeyboardView in your layout: http://developer.android.com/reference/android/inputmethodservice/KeyboardView.html
Use the same principle for the other views you want to handle: manage them yourself in your layout. I don't know if you can in the software you plan to do but this is a way which can work.
You can only get views which are managed by your application.
This includes all views except the status and navigation bars(for higher than HoneyComb). If you choose to have your own InputMethod, that view can be yours as well but you'll need to register the proper keyboard views. See this question for more on that.
Otherwise, if you want to get all the views in your window:
ViewGroup decor = (ViewGroup)activity.getWindow().getDecorView();
int count = decor.getChildCount();
for(int i = 0; i < count; i++) {
View view = decor.getChildAt(i); //voila
}
hey use this code this will help you to find if any dialog is created in your activity
class MyActivity extends Activity {
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Log.d("TAG", "New Window ATTACHED");
}
}
onAttachedToWindow will be called every time user creates new dialog or something
I have a View object on my Activity and I'd like to change the background resource of the view. More specifically, I'd like to toggle it.
So I'll need some logic like this:
if (myView.getBackgroundResource() == R.drawable.first) {
myView.setBackgroundResource(R.drawable.second);
}
else {
myView.setBackgroundResource(R.drawable.first);
}
The issue here being that there is no getBackgroundResource() method.
How can I obtain the resource a View is using for its background?
I don't think the View remembers what resource it is using after it gets the Drawable from the resource.
Why not use an instance variable in your Activity, or subclass the View and add an instance variable to it?
Wouldn't it be easier to just have a control variable that maintains the state? Lets you be flexible and allows you any number of drawables.
int[] backgrounds = {
R.drawable.first,
R.drawable.second,
R.drawable.third
};
int currentBg;
void switch() {
currentBg++;
currentBg %= backgrounds.length;
myView.setBackgroundResource(backgrounds[currentBg]);
}
You could use a flag to keep track of which was last set
private static final int FIRST_BG = 0;
private static final int SECOND_BG = 1;
private int mCurrentBg;
...
if (mCurrentBg == FIRST_BG) {
myView.setBackgroundResource(R.drawable.second);
mCurrentBg = SECOND_BG;
}
else {
myView.setBackgroundResource(R.drawable.first);
mCurrentBg = FIRST_BG;
}
You would have to initialize mCurrentBg wherever the background is initially set though.
You can get the ID of a resource via the getResources().getIdentifier("filename", "drawable", "com.example.android.project"); function. As you can see you will need the filename, the type of resource (drawable, layout or whatever) and the package it is in.
EDIT: Updated my logic fail.
I think you might be able to put the setTag() and getTag() methods to use here:
//set the background and tag initially
View v = (View)findViewById(R.id.view);
v.setBackgroundResource(R.drawable.first);
v.setTag(R.drawable.first);
if(v.getTag().equals(R.drawable.first)) {
v.setBackgroundResource(R.drawable.second);
v.setTag(R.drawable.second);
} else {
v.setBackgroundResource(R.drawable.first);
v.setTag(R.drawable.first);
}
I have not tested this, but I think it should work, in theory. The downside is that you add a little overhead by having to manually tag it the first time, but after the initial tagging, you shouldn't have to worry about keeping track of flags.