I am facing the issue with my Recycler view while placing Admob ads after every 5 items. First ads display after 5 items but when swept up/down the ads display random positions. What should I change to display ads after every 5 items?
AdapterFile:
public class TQuoteAdapter extends RecyclerView.Adapter<TQuoteAdapter.ImageHolder> {
private int ad_count = 0;
List<QuotesModel> quotesList;
Context context;
int width;
DBHelper_dbfile dbHelper;
int[] grid_colors;
int c = 0;
public TQuoteAdapter(List<QuotesModel> quotesList, Context context) {
this.quotesList = quotesList;
this.context = context;
dbHelper = new DBHelper_dbfile(context);
try {
dbHelper.openDatabase();
} catch (SQLException sqle) {
throw sqle;
}
DisplayMetrics displayMetrics = context.getResources()
.getDisplayMetrics();
width = displayMetrics.widthPixels;
grid_colors = context.getResources().getIntArray(R.array.grid_colors);
}
public static class ImageHolder extends RecyclerView.ViewHolder {
private NativeAdView nativeAdView;
ImageView favIV;
TextView quoteTV;
LinearLayout share, copy, wapp,fbapp,instaapp;
CardView cardView;
public ImageHolder(#NonNull View itemView) {
super(itemView);
nativeAdView = itemView.findViewById(R.id.native_ad_view);
quoteTV = itemView.findViewById(R.id.quoteTV);
favIV = itemView.findViewById(R.id.favIV);
share = itemView.findViewById(R.id.share);
copy = itemView.findViewById(R.id.copy);
wapp = itemView.findViewById(R.id.wapp);
fbapp = itemView.findViewById(R.id.fbapp);
instaapp = itemView.findViewById(R.id.instaapp);
cardView = itemView.findViewById(R.id.cardView);
}
}
#NonNull
#Override
public ImageHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_tquote, parent, false);
return new ImageHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ImageHolder holder, int position) {
if(ad_count == 5){
AdLoader adLoader = new AdLoader.Builder(context,context.getString(R.string.native_unit_id))
.forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
#Override
public void onNativeAdLoaded(#NonNull NativeAd nativeAd) {
populateNativeAdView(nativeAd,holder.nativeAdView);
if (onDestroy()) {
nativeAd.destroy();
}
}
})
.withAdListener(new AdListener() {
#Override
public void onAdFailedToLoad(LoadAdError adError) {
// Handle the failure by logging, altering the UI, and so on.
}
})
.withNativeAdOptions(new NativeAdOptions.Builder()
// Methods in the NativeAdOptions.Builder class can be
// used here to specify individual options settings.
.build())
.build();
adLoader.loadAd(new AdRequest.Builder().build());
ad_count = 0;
}else {
holder.quoteTV.setText(quotesList.get(position).getQuotes());
ad_count ++;
}
setAnimation(holder.itemView);
if (quotesList.get(position).getFavourite().equals("no")) {
holder.favIV.setImageResource(R.drawable.unpress_download);
} else {
holder.favIV.setImageResource(R.drawable.press_download);
}
holder.favIV.setOnClickListener(v -> {
if (Utills.hasPermissions(context, Utills.permissions)) {
ActivityCompat.requestPermissions((Activity) context, Utills.permissions, Utills.perRequest);
} else {
if (quotesList.get(position).getFavourite().equals("no")) {
dbHelper.addToFavourite("yes", quotesList.get(position).getId());
quotesList.get(position).setFavourite("yes");
} else {
dbHelper.addToFavourite("no", quotesList.get(position).getId());
quotesList.get(position).setFavourite("no");
}
notifyDataSetChanged();
}
});
int color = grid_colors[c];
c++;
if (c == grid_colors.length) {
c = 0;
}
holder.cardView.setCardBackgroundColor(color);
}
private void setAnimation(View view){
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
view.setAnimation(animation);
}
protected boolean onDestroy() {
AdManager.destroyFbAd();
return false;
}
#Override
public int getItemCount() {
return quotesList.size();
}
private void populateNativeAdView(NativeAd nativeAd, NativeAdView nativeAdView) {
nativeAdView.setMediaView((MediaView) nativeAdView.findViewById(R.id.media_view));
nativeAdView.setCallToActionView(nativeAdView.findViewById(R.id.cta));
nativeAdView.setHeadlineView(nativeAdView.findViewById(R.id.primary));
nativeAdView.setAdvertiserView(nativeAdView.findViewById(R.id.secondary));
nativeAdView.setStarRatingView(nativeAdView.findViewById(R.id.rating_bar));
nativeAdView.setBodyView(nativeAdView.findViewById(R.id.body));
nativeAdView.setIconView(nativeAdView.findViewById(R.id.icon));
View headlineView = nativeAdView.getHeadlineView();
Objects.requireNonNull(headlineView);
((AppCompatTextView) headlineView).setText(nativeAd.getHeadline());
View bodyView = nativeAdView.getBodyView();
Objects.requireNonNull(bodyView);
((AppCompatTextView) bodyView).setText(nativeAd.getBody());
View callToActionView = nativeAdView.getCallToActionView();
Objects.requireNonNull(callToActionView);
((AppCompatButton) callToActionView).setText(nativeAd.getCallToAction());
MediaView mediaView = nativeAdView.getMediaView();
Objects.requireNonNull(mediaView);
MediaContent mediaContent = nativeAd.getMediaContent();
Objects.requireNonNull(mediaContent);
mediaView.setMediaContent(mediaContent);
if (nativeAd.getIcon() == null) {
View iconView = nativeAdView.getIconView();
Objects.requireNonNull(iconView);
iconView.setVisibility(View.INVISIBLE);
} else {
View iconView2 = nativeAdView.getIconView();
Objects.requireNonNull(iconView2);
((AppCompatImageView) iconView2).setImageDrawable(nativeAd.getIcon().getDrawable());
nativeAdView.getIconView().setVisibility(View.VISIBLE);
}
if (nativeAd.getStarRating() == null) {
View starRatingView = nativeAdView.getStarRatingView();
Objects.requireNonNull(starRatingView);
starRatingView.setVisibility(View.INVISIBLE);
} else {
View starRatingView2 = nativeAdView.getStarRatingView();
Objects.requireNonNull(starRatingView2);
((RatingBar) starRatingView2).setRating(nativeAd.getStarRating().floatValue());
nativeAdView.getStarRatingView().setVisibility(View.VISIBLE);
}
if (nativeAd.getAdvertiser() == null) {
View advertiserView = nativeAdView.getAdvertiserView();
Objects.requireNonNull(advertiserView);
advertiserView.setVisibility(View.INVISIBLE);
} else {
View advertiserView2 = nativeAdView.getAdvertiserView();
Objects.requireNonNull(advertiserView2);
((AppCompatTextView) advertiserView2).setText(nativeAd.getAdvertiser());
nativeAdView.getAdvertiserView().setVisibility(View.VISIBLE);
}
nativeAdView.setNativeAd(nativeAd);
nativeAdView.setVisibility(View.VISIBLE);
}
Related
What changes do I need to make to the following code to get an m3u8 link to play?
I'm able to get regular MP4 videos to work, but not HLS. What would I need to do to make HLS links to work?
I would like to implement something like this, that allows for playback of different media sources. https://gist.github.com/navi25/7ab41931eb52bbcb693b5599e6955245#file-mediasourcebuilder-kt
public class VideoPlayerRecyclerView extends RecyclerView {
private static final String TAG = "VideoPlayerRecyclerView";
private enum VolumeState {ON, OFF};
// ui
private ImageView thumbnail, volumeControl;
private ProgressBar progressBar;
private View viewHolderParent;
private FrameLayout frameLayout;
private PlayerView videoSurfaceView;
private SimpleExoPlayer videoPlayer;
// vars
private ArrayList<MediaObject> mediaObjects = new ArrayList<>();
private int videoSurfaceDefaultHeight = 0;
private int screenDefaultHeight = 0;
private Context context;
private int playPosition = -1;
private boolean isVideoViewAdded;
private RequestManager requestManager;
// controlling playback state
private VolumeState volumeState;
public VideoPlayerRecyclerView(#NonNull Context context) {
super(context);
init(context);
}
public VideoPlayerRecyclerView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
this.context = context.getApplicationContext();
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point point = new Point();
display.getSize(point);
videoSurfaceDefaultHeight = point.x;
screenDefaultHeight = point.y;
videoSurfaceView = new PlayerView(this.context);
videoSurfaceView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
// 2. Create the player
videoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
// Bind the player to the view.
videoSurfaceView.setUseController(false);
videoSurfaceView.setPlayer(videoPlayer);
setVolumeControl(VolumeState.ON);
addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
Log.d(TAG, "onScrollStateChanged: called.");
if(thumbnail != null){ // show the old thumbnail
thumbnail.setVisibility(VISIBLE);
}
// There's a special case when the end of the list has been reached.
// Need to handle that with this bit of logic
if(!recyclerView.canScrollVertically(1)){
playVideo(true);
}
else{
playVideo(false);
}
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
addOnChildAttachStateChangeListener(new OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(View view) {
}
#Override
public void onChildViewDetachedFromWindow(View view) {
if (viewHolderParent != null && viewHolderParent.equals(view)) {
resetVideoView();
}
}
});
videoPlayer.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
Log.e(TAG, "onPlayerStateChanged: Buffering video.");
if (progressBar != null) {
progressBar.setVisibility(VISIBLE);
}
break;
case Player.STATE_ENDED:
Log.d(TAG, "onPlayerStateChanged: Video ended.");
videoPlayer.seekTo(0);
break;
case Player.STATE_IDLE:
break;
case Player.STATE_READY:
Log.e(TAG, "onPlayerStateChanged: Ready to play.");
if (progressBar != null) {
progressBar.setVisibility(GONE);
}
if(!isVideoViewAdded){
addVideoView();
}
break;
default:
break;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
}
public void playVideo(boolean isEndOfList) {
int targetPosition;
if(!isEndOfList){
int startPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
int endPosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
// if there is more than 2 list-items on the screen, set the difference to be 1
if (endPosition - startPosition > 1) {
endPosition = startPosition + 1;
}
// something is wrong. return.
if (startPosition < 0 || endPosition < 0) {
return;
}
// if there is more than 1 list-item on the screen
if (startPosition != endPosition) {
int startPositionVideoHeight = getVisibleVideoSurfaceHeight(startPosition);
int endPositionVideoHeight = getVisibleVideoSurfaceHeight(endPosition);
targetPosition = startPositionVideoHeight > endPositionVideoHeight ? startPosition : endPosition;
}
else {
targetPosition = startPosition;
}
}
else{
targetPosition = mediaObjects.size() - 1;
}
Log.d(TAG, "playVideo: target position: " + targetPosition);
// video is already playing so return
if (targetPosition == playPosition) {
return;
}
// set the position of the list-item that is to be played
playPosition = targetPosition;
if (videoSurfaceView == null) {
return;
}
// remove any old surface views from previously playing videos
videoSurfaceView.setVisibility(INVISIBLE);
removeVideoView(videoSurfaceView);
int currentPosition = targetPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
View child = getChildAt(currentPosition);
if (child == null) {
return;
}
VideoPlayerViewHolder holder = (VideoPlayerViewHolder) child.getTag();
if (holder == null) {
playPosition = -1;
return;
}
thumbnail = holder.thumbnail;
progressBar = holder.progressBar;
volumeControl = holder.volumeControl;
viewHolderParent = holder.itemView;
requestManager = holder.requestManager;
frameLayout = holder.itemView.findViewById(R.id.media_container);
videoSurfaceView.setPlayer(videoPlayer);
viewHolderParent.setOnClickListener(videoViewClickListener);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
context, Util.getUserAgent(context, "RecyclerView VideoPlayer"));
String mediaUrl = mediaObjects.get(targetPosition).getMedia_url();
if (mediaUrl != null) {
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(mediaUrl));
videoPlayer.prepare(videoSource);
videoPlayer.setPlayWhenReady(true);
}
}
private OnClickListener videoViewClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
toggleVolume();
}
};
/**
* Returns the visible region of the video surface on the screen.
* if some is cut off, it will return less than the #videoSurfaceDefaultHeight
* #param playPosition
* #return
*/
private int getVisibleVideoSurfaceHeight(int playPosition) {
int at = playPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
Log.d(TAG, "getVisibleVideoSurfaceHeight: at: " + at);
View child = getChildAt(at);
if (child == null) {
return 0;
}
int[] location = new int[2];
child.getLocationInWindow(location);
if (location[1] < 0) {
return location[1] + videoSurfaceDefaultHeight;
} else {
return screenDefaultHeight - location[1];
}
}
// Remove the old player
private void removeVideoView(PlayerView videoView) {
ViewGroup parent = (ViewGroup) videoView.getParent();
if (parent == null) {
return;
}
int index = parent.indexOfChild(videoView);
if (index >= 0) {
parent.removeViewAt(index);
isVideoViewAdded = false;
viewHolderParent.setOnClickListener(null);
}
}
private void addVideoView(){
frameLayout.addView(videoSurfaceView);
isVideoViewAdded = true;
videoSurfaceView.requestFocus();
videoSurfaceView.setVisibility(VISIBLE);
videoSurfaceView.setAlpha(1);
thumbnail.setVisibility(GONE);
}
private void resetVideoView(){
if(isVideoViewAdded){
removeVideoView(videoSurfaceView);
playPosition = -1;
videoSurfaceView.setVisibility(INVISIBLE);
thumbnail.setVisibility(VISIBLE);
}
}
public void releasePlayer() {
if (videoPlayer != null) {
videoPlayer.release();
videoPlayer = null;
}
viewHolderParent = null;
}
private void toggleVolume() {
if (videoPlayer != null) {
if (volumeState == VolumeState.OFF) {
Log.d(TAG, "togglePlaybackState: enabling volume.");
setVolumeControl(VolumeState.ON);
} else if(volumeState == VolumeState.ON) {
Log.d(TAG, "togglePlaybackState: disabling volume.");
setVolumeControl(VolumeState.OFF);
}
}
}
private void setVolumeControl(VolumeState state){
volumeState = state;
if(state == VolumeState.OFF){
videoPlayer.setVolume(0f);
animateVolumeControl();
}
else if(state == VolumeState.ON){
videoPlayer.setVolume(1f);
animateVolumeControl();
}
}
private void animateVolumeControl(){
if(volumeControl != null){
volumeControl.bringToFront();
if(volumeState == VolumeState.OFF){
requestManager.load(R.drawable.ic_volume_off_grey_24dp)
.into(volumeControl);
}
else if(volumeState == VolumeState.ON){
requestManager.load(R.drawable.ic_volume_up_grey_24dp)
.into(volumeControl);
}
volumeControl.animate().cancel();
volumeControl.setAlpha(1f);
volumeControl.animate()
.alpha(0f)
.setDuration(600).setStartDelay(1000);
}
}
public void setMediaObjects(ArrayList<MediaObject> mediaObjects){
this.mediaObjects = mediaObjects;
}
}
You need to use HlsMediaSource instead of the default MediaSource for HLS.
Media sources
I need your help I am new in android programming. How can I save all the content in the list view save into text file this is my code of try to save the file but the problem is how can i put the listview array list to get the data i don't know how to put it where to put it please help how to do it to save the content of my listview
Button code:
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
File myFile = new File("/sdcard/mysdfile.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
for (int i = 0; i < ChatBubbles.length; i++) {
myOutWriter.append(ChatBubbles[i] +"\n");
}
myOutWriter.close();
fOut.close();
Toast.makeText(getBaseContext(),
"Done writing SD 'mysdfile.txt'",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
Chatbubble class:
package com.example.ezminute;
public class ChatBubble {
private String content;
private boolean myMessage;
public ChatBubble(String content, boolean myMessage) {
this.content = content;
this.myMessage = myMessage;
}
public String getContent() {
return content;
}
public boolean myMessage() {
return myMessage;
}
}
MessageAdapter:
package com.example.ezminute;
public class MessageAdapter extends ArrayAdapter<ChatBubble> {
private Activity activity;
private List<ChatBubble> messages;
public MessageAdapter(Activity context, int resource, List<ChatBubble> objects) {
super(context, resource, objects);
this.activity = context;
this.messages = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
int layoutResource = 0; // determined by view type
ChatBubble ChatBubble = getItem(position);
int viewType = getItemViewType(position);
if (ChatBubble.myMessage()) {
layoutResource = R.layout.left_chat_bubble;
} else {
layoutResource = R.layout.right_chat_bubble;
}
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
convertView = inflater.inflate(layoutResource, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
//set message content
holder.msg.setText(ChatBubble.getContent());
return convertView;
}
#Override
public int getViewTypeCount() {
// return the total number of view types. this value should never change
// at runtime. Value 2 is returned because of left and right views.
return 2;
}
#Override
public int getItemViewType(int position) {
// return a value between 0 and (getViewTypeCount - 1)
return position % 2;
}
private class ViewHolder {
private TextView msg;
public ViewHolder(View v) {
msg = (TextView) v.findViewById(R.id.txt_msg);
}
}
}
I want to refresh the getview() of baseadapter each time when user click on multispinner. Also wants to deselect all the selected checkbox.
Anybody please help.
Blockquote
Below is my multispinner java class
public class MultiSpinnerSearch extends Spinner implements OnCancelListener {
private static final String TAG = MultiSpinnerSearch.class.getSimpleName();
private List<KeyPairBoolData> items;
private String defaultText = "";
private String spinnerTitle = "";
private SpinnerListener listener;
private int limit = 0;
private int selected = 0;
private LimitExceedListener limitListener;
MyAdapter adapter;
public static AlertDialog.Builder builder;
public static AlertDialog ad;
public MultiSpinnerSearch(Context context) {
super(context);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
TypedArray a = arg0.obtainStyledAttributes(arg1, R.styleable.MultiSpinnerSearch);
limit = a.getIndexCount();
for (int i = 0; i < limit; ++i) {
int attr = a.getIndex(i);
if (attr == R.styleable.MultiSpinnerSearch_hintText) {
spinnerTitle = a.getString(attr);
defaultText = spinnerTitle;
break;
}
}
Log.i(TAG, "spinnerTitle: " + spinnerTitle);
a.recycle();
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
public void setLimit(int limit, LimitExceedListener listener) {
this.limit = limit;
this.limitListener = listener;
}
public List<KeyPairBoolData> getSelectedItems() {
List<KeyPairBoolData> selectedItems = new ArrayList<>();
for (KeyPairBoolData item : items) {
if (item.isSelected()) {
selectedItems.add(item);
}
}
return selectedItems;
}
public List<Long> getSelectedIds() {
List<Long> selectedItemsIds = new ArrayList<>();
for (KeyPairBoolData item : items) {
if (item.isSelected()) {
selectedItemsIds.add(item.getId());
}
}
return selectedItemsIds;
}
#Override
public void onCancel(DialogInterface dialog) {
// refresh text on spinner
StringBuilder spinnerBuffer = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
String spinnerText = spinnerBuffer.toString();
if (spinnerText.length() > 2)
spinnerText = defaultText;
else
spinnerText = defaultText;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<>(getContext(), R.layout.textview_for_spinner, new String[]{spinnerText});
setAdapter(adapterSpinner);
if (adapter != null)
adapter.notifyDataSetChanged();
listener.onItemsSelected(items);
}
#Override
public boolean performClick() {
builder = new AlertDialog.Builder(new ContextThemeWrapper(getContext(), R.style.Material_App_Dialog));
builder.setTitle(spinnerTitle);
final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View view = inflater.inflate(R.layout.alert_dialog_listview_search, null);
builder.setView(view);
final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setFastScrollEnabled(false);
adapter = new MyAdapter(getContext(), items);
listView.setAdapter(adapter);
final TextView emptyText = (TextView) view.findViewById(R.id.empty);
listView.setEmptyView(emptyText);
final EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
builder.setPositiveButton("Done", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.i(TAG, " ITEMS : " + items.size());
dialog.cancel();
}
});
builder.setOnCancelListener(this);
ad = builder.show();
return true;
}
public void setItems(List<KeyPairBoolData> items, int position, SpinnerListener listener) {
this.items = items;
this.listener = listener;
StringBuilder spinnerBuffer = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
if (spinnerBuffer.length() > 2)
defaultText = spinnerBuffer.toString().substring(0, spinnerBuffer.toString().length() - 2);
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<>(getContext(), R.layout.textview_for_spinner, new String[]{defaultText});
setAdapter(adapterSpinner);
if (position != -1) {
items.get(position).setSelected(true);
//listener.onItemsSelected(items);
onCancel(null);
}
}
public interface LimitExceedListener {
void onLimitListener(KeyPairBoolData data);
}
//Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
List<KeyPairBoolData> arrayList;
List<KeyPairBoolData> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<KeyPairBoolData> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView textView;
CheckBox checkBox;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
Log.i(TAG, "getView() enter");
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.item_listview_multiple, parent, false);
holder.textView = (TextView) convertView.findViewById(R.id.alertTextView);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.alertCheckbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final int backgroundColor = (position % 2 == 0) ? R.color.list_background : R.color.list_background;
convertView.setBackgroundColor(ContextCompat.getColor(getContext(), backgroundColor));
if (position==0)
{
holder.textView.setTextColor(Color.BLACK);
}
if (position==3)
{
holder.textView.setTextColor(Color.GREEN);
convertView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.list_selected));
}
final KeyPairBoolData data = arrayList.get(position);
holder.textView.setText(data.getName());
holder.textView.setTypeface(null, Typeface.NORMAL);
holder.checkBox.setChecked(data.isSelected());
convertView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (data.isSelected()) { // unselect
selected--;
} else if (selected == limit) { // select with limit
if (limitListener != null)
limitListener.onLimitListener(data);
return;
} else { // selected
selected++;
}
final ViewHolder temp = (ViewHolder) v.getTag();
temp.checkBox.setChecked(!temp.checkBox.isChecked());
data.setSelected(!data.isSelected());
Log.i(TAG, "On Click Selected Item : " + data.getName() + " : " + data.isSelected());
}
});
holder.checkBox.setTag(holder);
return convertView;
}
#SuppressLint("DefaultLocale")
#Override
public Filter getFilter() {
return new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arrayList = (List<KeyPairBoolData>) results.values; // has the filtered values
notifyDataSetChanged(); // notifies the data with new filtered values
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values
List<KeyPairBoolData> FilteredArrList = new ArrayList<>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<>(arrayList); // saves the original data in mOriginalValues
}
/********
*
* If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
* else does the Filtering and returns FilteredArrList(Filtered)
*
********/
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = mOriginalValues.size();
results.values = mOriginalValues;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mOriginalValues.size(); i++) {
Log.i(TAG, "Filter : " + mOriginalValues.get(i).getName() + " -> " + mOriginalValues.get(i).isSelected());
String data = mOriginalValues.get(i).getName();
if (data.toLowerCase().contains(constraint.toString())) {
FilteredArrList.add(mOriginalValues.get(i));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
}
}
}
And from my main activity
MultiSpinnerSearch searchSpinner = (MultiSpinnerSearch) findViewById(R.id.searchMultiSpinner);
searchSpinner.setItems(listArray, -1, new SpinnerListener() {
#Override
public void onItemsSelected(List<KeyPairBoolData> items) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
Log.i("TAG", i + " : " + items.get(i).getName() + " : " + items.get(i).isSelected());
FlashMessage(i + " : " + items.get(i).getName() + " : " + items.get(i).isSelected());
if (GroupName.equals(""))
{
GroupName=GroupName+items.get(i).getName();
Group_stuid=Group_stuid+student_idlist[i+1];
}
else
{
GroupName=GroupName+","+items.get(i).getName();
Group_stuid=Group_stuid+"#"+student_idlist[i+1];
}
}
}
FlashMessage("grp name : "+GroupName);
FlashMessage("grp id : "+Group_stuid);
Audiofilename=appfunct.checkfile(eventType,acdses_sct,class_sct,category_sct,subject_sct,test_sct,Group_stuid,GroupName);
outfolder=appfunct.outfldr();
Group_stuid=Group_stuid.replaceAll("/","-");
File create_stuid=new File(outfolder.toString()+"/"+Group_stuid);
if(!create_stuid.exists()) {
create_stuid.mkdirs();
}
FlashMessage(""+GroupFoldername);
Group_listFiles=appfunct.showlistfiles(GroupFoldername);
if (Group_listFiles != null)
{
final CustomGroupFolder_ListDispaly adapter1 = new CustomGroupFolder_ListDispaly(Group_recording.this,R.layout.group_item_listview,Group_listFiles);
group_listview.setAdapter(adapter1);
}
GroupName="";
Group_stuid="";
selected_students=appfunct.getSelectedNamesGroup(GroupFoldername);
}
});
FlashMessage("out : grp id "+Group_stuid);
searchSpinner.setLimit(2, new MultiSpinnerSearch.LimitExceedListener() {
#Override
public void onLimitListener(KeyPairBoolData data) {
Toast.makeText(getApplicationContext(),
"Limit exceed ", Toast.LENGTH_LONG).show();
}
});
apply this to your adapter adapter.notifyDataSetChanged();
Hi I am trying to upgrade our ios app from mvvmcross v1 to v3. I can't figure out how to make my custom buttonrow work.
My view ViewDidLoad it is the button items that binds to the button row
public override void ViewDidLoad()
{
base.ViewDidLoad();
SortingView.ViewModel = ViewModel;
_shown = false;
// Setup View Animatons
Buttons.OnClick = () => { AnimationTransition = ViewTransitionAnimation.TransitionFade; };
TopRightButton.TouchDown +=
(sender, args) => {
AnimationTransition = ViewTransitionAnimation.TransitionCrossDissolve;
};
// Setup Bindings
this.AddBindings(
new Dictionary<object, string>
{
{this.BackgroundImage, "{'ImageData':{'Path':'BackgroundImage','Converter':'ImageItem'}}"},
{this.TopbarBackground, "{'ImageData':{'Path':'TopBarImage','Converter':'ImageItem'}}"},
{this.TopLogo, "{'ImageData':{'Path':'Logo','Converter':'ImageItem'}}"},
{this.Buttons, "{'ItemsSource':{'Path':'ButtonItems'}}"},
{this.SlideMenu, "{'ItemsSource':{'Path':'VisibleViews'}}"},
{
this.SortingView,
"{'ItemsSource':{'Path':'CategoriesName'},'SelectedGroups':{'Path':'SelectedGroups'},'ForceUbracoUpdateAction':{'Path':'ForceUbracoUpdateAction'}}"
},
{this.SettingsButton, "{'TouchDown':{'Path':'TopRightButtonClick'},'Hide':{'Path':'HideTopbarButton'},'ImageData':{'Path':'TopButtonImage','Converter':'ImageItem'}}" },
{this.TopRightButton, "{'TouchDown':{'Path':'SecondaryButtonButtonPushed'},'Hide':{'Path':'HideTopbarButton2'},'ImageData':{'Path':'SettingsButtonImage','Converter':'ImageItem'}}" }
});
// Perform any additional setup after loading the view, typically from a nib.
NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidBecomeActiveNotification, ReEnableSlideMenu);
this.SortingView.Hidden=true;
ViewModel.SettingButtonEvent += HandleSettingButtonPushed;
}
Here is my custom control "ButtonRow
[Register("ButtonRow")]
public class ButtonRow : CustomListViewController
{
private int _width = 0;
private UIImage _backgroundImage = null;
public ButtonRow(IntPtr handle)
: base(handle)
{
_width = (int)this.Frame.Width;
UseImageAsIcon = false;
FontSize=0;
}
public bool UseImageAsIcon { get; set; }
public UIImage BackgroundImage
{
get { return _backgroundImage; }
set { _backgroundImage = value; }
}
public int FontSize
{
get;set;
}
private Action _onClickAction;
private int _spacing = 0;
public Action OnClick
{
get
{
return _onClickAction;
}
set
{
_onClickAction = value;
}
}
/// <summary>
/// The add views.
/// </summary>
/// custom implementation for adding views to the button row
protected override void AddViews()
{
if (ItemsSource == null)
{
Hidden = true;
return;
}
base.AddViews();
foreach (UIView uiView in Subviews)
{
uiView.RemoveFromSuperview();
}
if (ItemsSource.Count == 0)
{
Hidden = true;
return;
}
if (_backgroundImage != null)
{
var frame = new RectangleF(0, 0, Frame.Width, Frame.Height);
var background = new UIImageView(frame) { Image = _backgroundImage };
AddSubview(background);
}
_width = _width - ((ItemsSource.Count - 1) * Spacing);
var buttonWidth = (int)Math.Ceiling (((double)_width) / ItemsSource.Count);
int index = 0;
foreach (ViewItemModel item in ItemsSource)
{
// creating custom button with needed viewmodel, nib etc is loaded in the class constructor
var button = new ButtonWithLabel(item, OnClick);
if (FontSize > 0)
{
button.FontSize(FontSize);
}
if (UseImageAsIcon)
{
button.AddBindings(
new Dictionary<object, string>
{
{ button, "{'IconLabel':{'Path':'Title'},'TitleFontColor':{'Path':'TitleFontColor'}}" },
{ button.icon, "{'ImageData':{'Path':'ImageIcon','Converter':'ImageItem'}}" }
});
}
else
{
// bindings created between the button and its viewmodel
button.AddBindings(
new Dictionary<object, string>
{
{button, "{'Label':{'Path':'Title'},'TitleFontColor':{'Path':'TitleFontColor'},'BackgroundColor':{'Path':'BackgroundColor'}}" },
{button.Background, "{'ImageData':{'Path':'ImageIcon','Converter':'ImageItem'}}" }
});
button.icon.Hidden = true;
}
// new frame of button is set, as the number of buttons is dynamic
int x = index == 0 ? 0 : index * (buttonWidth + Spacing);
button.SetFrame(new RectangleF(x, 0, buttonWidth, Frame.Height));
// the view of the button is added to the buttonrow view
AddSubview(button.View);
index++;
}
}
public int Spacing
{
get
{
return this._spacing;
}
set
{
this._spacing = value;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
public override void Cleanup()
{
if(Subviews!=null)
{
foreach (var view in Subviews)
{
view.RemoveFromSuperview();
}
}
if(_backgroundImage!=null)
{
_backgroundImage.Dispose();
}
ItemsSource = null;
}
}
Here is my CustomListViewController
public class CustomListViewController: UIView
{
private IList _itemsSource;
private CustomViewSource _viewSource;
public CustomListViewController(MvxShowViewModelRequest showRequest)
{
ShowRequest = showRequest;
}
protected CustomListViewController()
{
}
public CustomListViewController(IntPtr handle)
: base(handle)
{
}
public bool IsVisible
{
get
{
return this.IsVisible;
}
}
public IList ItemsSource
{
get { return _itemsSource; }
set { _itemsSource = value; if(value!=null){CreateViewSource(_itemsSource); }}
}
public virtual void CreateViewSource(IList items)
{
if (_viewSource == null)
{
_viewSource = new CustomViewSource();
_viewSource.OnNewViewsReady += FillViews;
}
_viewSource.ItemsSource = items;
}
private void FillViews(object sender, EventArgs e)
{
AddViews();
}
protected virtual void AddViews()
{
// get views from source and do custom allignment
}
public virtual void Cleanup()
{
if(_viewSource!=null)
{
_itemsSource.Clear();
_itemsSource=null;
_viewSource.OnNewViewsReady -= FillViews;
_viewSource.ItemsSource.Clear();
_viewSource.ItemsSource = null;
_viewSource=null;
}
}
public MvxShowViewModelRequest ShowRequest { get;
private set;
}
}
And My CustomViewSource
public class CustomViewSource
{
private IList _itemsSource;
private List<UIView> _views=new List<UIView>();
public event EventHandler<EventArgs> OnNewViewsReady;
public CustomViewSource ()
{
}
public List<UIView> Views { get { return _views; } }
public virtual IList ItemsSource
{
get { return _itemsSource; }
set
{
// if (_itemsSource == value)
// return;
var collectionChanged = _itemsSource as INotifyCollectionChanged;
if (collectionChanged != null)
collectionChanged.CollectionChanged -= CollectionChangedOnCollectionChanged;
_itemsSource = value;
collectionChanged = _itemsSource as INotifyCollectionChanged;
if (collectionChanged != null)
collectionChanged.CollectionChanged += CollectionChangedOnCollectionChanged;
ReloadViewData();
}
}
protected object GetItemAt(int position)
{
if (ItemsSource == null)
return null;
return ItemsSource[position];
}
protected void CollectionChangedOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
ReloadViewData();
}
protected virtual void ReloadViewData()
{
if(ItemsSource==null){return;}
foreach (var VARIABLE in ItemsSource)
{
//call create view and add it to Views
}
//event new views created
if(OnNewViewsReady!=null)
OnNewViewsReady(this,new EventArgs());
}
protected virtual UIView CreateUIView(int position)
{
UIView view = null;
/*
//create view from nib
UIView newView=null;
return newView;
* */
return view;
}
}
Any one have any clues on how to make this work in mvvmcross v3 ?
I would like to make it so i can add x number of buttons and load the buttons from nib files. Have looked at the Kittens collection view example, but have not figured out how to make it work for my buttonRow, not sure if the collectionView is the right one to use as base.
The most common way to show a list is to use a UITableView.
There are quite a few samples around that show how to load these in MvvmCross:
n=2 and n=2.5 in http://mvvmcross.wordpress.com/
n=6 and n=6.5 in http://mvvmcross.wordpress.com/
Working with Collections in https://github.com/MvvmCross/MvvmCross-Tutorials/tree/master/Working%20With%20Collections
In your case, it looks like the previous coder has implemented some sort of custom control with custom layout. Adapting this to v3 shouldn't be particularly difficult, but you are going to need to read through and understand the previous code and how it works (this is nothing to do with MvvmCross - it's just app UI code).
One sample on dealing with custom views like this in iOS is the N=32 tutorial - http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html
I have a program in android and i have a button on the group of expandableListView,I have 4 groups, so i need to control those 4 buttons individually, different activities for each.
Can anyone help me?
Code for MainActivity:
public class MainActivity extends Activity {
final Context context = this;
private static final String[][] data = {{" "},{"a1","a2"},{"s1","s2","s3"},{"t1","t2","t3"}};
private ExpandableListView expandableListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView)findViewById(R.id.lvExp);
expandableListView.setAdapter(new ExpandableListAdapter(context, this, data));
}
Here`s my code for Adapter:
class ExpandableListAdapter extends BaseExpandableListAdapter {
public Context context;
CheckBox checkBox;
private LayoutInflater vi;
private String[][] data;
int _objInt;
public static Boolean checked[] = new Boolean[1];
HashMap<Long,Boolean> checkboxMap = new HashMap<Long,Boolean>();
private static final int GROUP_ITEM_RESOURCE = R.layout.list_group;
private static final int CHILD_ITEM_RESOURCE = R.layout.list_item;
public String []check_string_array;
public ExpandableListAdapter(Context context, Activity activity, String[][] data) {
this.data = data;
this.context = context;
vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
_objInt = data.length;
check_string_array = new String[_objInt];
popolaCheckMap();
}
public void popolaCheckMap(){
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
String buffer = null;
for(int i=0; i<_objInt; i++){
buffer = settings.getString(String.valueOf((int)i),"false");
if(buffer.equals("false"))
checkboxMap.put((long)i, false);
else checkboxMap.put((long)i, true);
}
}
public class CheckListener implements OnCheckedChangeListener{
long pos;
public void setPosition(long p){
pos = p;
}
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Log.i("checkListenerChanged", String.valueOf(pos)+":"+String.valueOf(isChecked));
checkboxMap.put(pos, isChecked);
if(isChecked == true) check_string_array[(int)pos] = "true";
else check_string_array[(int)pos] = "false";
// save checkbox state of each group
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor preferencesEditor = settings.edit();
preferencesEditor.putString(String.valueOf((int)pos), check_string_array[(int)pos]);
preferencesEditor.commit();
}
}
public String getChild(int groupPosition, int childPosition) {
return data[groupPosition][childPosition];
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public int getChildrenCount(int groupPosition) {
return data[groupPosition].length;
}
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View v = convertView;
String child = getChild(groupPosition, childPosition);
int id_res = 0;
if(groupPosition == 0){
if(childPosition == 0) id_res = R.drawable.ic_launcher;
}
else if(groupPosition == 1){
}
else if(groupPosition == 2){
}
else if(groupPosition == 3){
}
if (child != null) {
v = vi.inflate(CHILD_ITEM_RESOURCE, null);
ViewHolder holder = new ViewHolder(v);
holder.text.setText(Html.fromHtml(child));
holder.imageview.setImageResource(id_res);
}
return v;
}
public String getGroup(int groupPosition) {
return "group-" + groupPosition;
}
public int getGroupCount() {
return data.length;
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View v = convertView;
String group = null;
int id_res = 0;
long group_id = getGroupId(groupPosition);
if(group_id == 0){
group = "Power Consumption";
}
else if(group_id == 1){
group = "Appliances";
}
else if(group_id == 2){
group = "Scenes";
}
else if(group_id == 3){
group = "Triggers";
}
if (group != null) {
v = vi.inflate(GROUP_ITEM_RESOURCE, null);
ViewHolder holder = new ViewHolder(v);
holder.text.setText(Html.fromHtml(group));
holder.imageview.setImageResource(id_res);
holder.imageview.setFocusable(false);
CheckListener checkL = new CheckListener();
checkL.setPosition(group_id);
}
return v;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public boolean hasStableIds() {
return true;
}
}
class ViewHolder {
public TextView text;
public ImageView imageview;
public ViewHolder(View v) {
this.text = (TextView)v.findViewById(R.id.text1);
this.imageview = (ImageView)v.findViewById(R.id.image1);
}
}