Creating a rectangle within a class - visual-studio-2010

So basically I'm trying to figure out how to implement rectangles with in a class around each bullet I fire. It's a missile command type game. What I can't figure out is WHERE I would declare the Rectangle and how I would pass it to the game.
Here the code for my rocket class...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ShootingRocket
{
public class Rocket
{
public Texture2D DrawTexture { get; set; }
public Vector2 Position { get; set; }
public Vector2 Direction { get; set; }
public float Rotation { get; set; }
public float Speed { get; set; }
public bool IsShooting { get; set; }
int timeBetweenShots = 100;
int shotTimer = 0;
public Rocket(Texture2D texture, Vector2 position, Vector2 direction, float rotation, float Speed)
{
this.DrawTexture = texture;
this.Position = position;
this.Direction = direction;
this.Rotation = rotation;
this.Speed = Speed;
this.IsShooting = false;
}
public void Update(GameTime gameTime)
{
this.Position += Direction * Speed;
if (IsShooting)
{
shotTimer += gameTime.ElapsedGameTime.Milliseconds;
if (shotTimer > timeBetweenShots)
{
shotTimer = 0;
ProjectileManager.AddBullet(this.Position, this.Direction, 12, 2000, BulletType.Player);
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(
this.DrawTexture,
this.Position,
null,
Color.White,
this.Rotation,
new Vector2(
this.DrawTexture.Width / 2,
this.DrawTexture.Height / 2),
1.0f,
SpriteEffects.None,
1.0f);
Here is the code for my bullet class...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ShootingRocket
{
public enum BulletType { Player, Enemy }
public class Bullet
{
public BulletType Type { get; set; }
public Texture2D DrawTexture { get; set; }
public Vector2 Position { get; set; }
public Vector2 Direction { get; set; }
public float Speed { get; set; }
public int ActiveTime { get; set; }
public int TotalActiveTime { get; set; }
public Bullet(Texture2D texture, Vector2 position, Vector2 direction, float speed, int activeTime, BulletType type)
{
this.DrawTexture = texture;
this.Position = position;
this.Direction = direction;
this.Speed = speed;
this.ActiveTime = activeTime;
this.Type = type;
this.TotalActiveTime = 0;
}
public void Update(GameTime gameTime)
{
this.Position += Direction * Speed;
this.TotalActiveTime += gameTime.ElapsedGameTime.Milliseconds;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(
DrawTexture,
Position,
null,
Color.White,
0f,
new Vector2(
DrawTexture.Width / 2,
DrawTexture.Height / 2),
1.0f,
SpriteEffects.None,
0.8f);
}
}
}
And last but not least my Projectile Manager class...
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace ShootingRocket
{
public class ProjectileManager : DrawableGameComponent
{
static List<Bullet> bullets = new List<Bullet>();
static Texture2D playerBulletTexture;
SpriteBatch spriteBatch;
public ProjectileManager(Game game, SpriteBatch spriteBatch)
: base(game)
{
game.Components.Add(this);
playerBulletTexture = game.Content.Load<Texture2D>("Bullet");
this.spriteBatch = spriteBatch;
}
public override void Update(GameTime gameTime)
{
for(int i = 0; i < bullets.Count; i++)
{
bullets[i].Update(gameTime);
if (bullets[i].TotalActiveTime > bullets[i].ActiveTime)
bullets.RemoveAt(i);
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
foreach (Bullet b in bullets)
{
b.Draw(spriteBatch);
}
base.Draw(gameTime);
}
public static void AddBullet(Vector2 position, Vector2 direction, float speed, int activeTime, BulletType type)
{
bullets.Add(new Bullet(playerBulletTexture, position, direction, speed, activeTime, type));
}
}
}
any help is GREATLY appreciated!

public Rectangle collisionRec {get; private set;}
Then in the update method of the bullet you update the rectangle coordinates.
collisionRec = new Rectangle(position.X, position.Y, spriteWidth, spriteHeight);
You are probably maintaining a list of all those bullets in game1 or somewhere.
foreach (Bullet b in bulletList)
{
if (b.collisionRec.Intersects(someOtherRec))
{
//Do some stuff.
}
}

Related

quiz template in unity issue

i've done this unity project following a youtube tutorial.
but i is not working can you figure out the problem??
ok so the first code is
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AnswerScript : MonoBehaviour
{
public bool isCorrect = false;
public QuizManager quizManager;
public Color startc;
private void Start()
{
startc = GetComponent<Image>().color;
}
public void Answer()
{
if (isCorrect)
{
GetComponent<Image>().color = Color.green;
Debug.Log("Correct Answer");
quizManager.correct();
}
else
{
GetComponent<Image>().color = Color.red;
Debug.Log("Wrong Answer");
quizManager.wrong();
}
}
}
and the second is this one it is a little script
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class QuestionAndANWSER
{
public Image[] Question;
public string[] Answers;
public int CorrectAnswer;
}
the third is this one the biggest script:)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class QuizManager : MonoBehaviour
{
public List<QuestionAndANWSER> Qna;
public GameObject[] options;
public int currentQuestion;
public GameObject QuizPanel;
public GameObject GOPanel;
public Text QuestionTxt;
public Text ScoreTxt;
int totalQuestions = 0;
public int score;
private void Start()
{
totalQuestions = Qna.Count;
GOPanel.SetActive(false);
generateQuestion();
}
public void retry()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
public void GameOver()
{
QuizPanel.SetActive(false);
GOPanel.SetActive(true);
ScoreTxt.text = score +"/"+ totalQuestions;
}
public void correct()
{
score += 1;
Qna.RemoveAt(currentQuestion);
StartCoroutine(WaitforNext());
}
public void wrong()
{
Qna.RemoveAt(currentQuestion);
StartCoroutine(WaitforNext());
}
IEnumerator WaitforNext()
{
yield return new WaitForSeconds(1);
generateQuestion();
}
void SetAnswer()
{
for (int i= 0; i < options.Length; i++)
{
options[i].GetComponent<Image>().color = options[i].GetComponent<AnswerScript>().startc;
options[i].GetComponent<AnswerScript>().isCorrect = false;
options[i].transform.GetChild(0).GetComponent<Text>().text = Qna[currentQuestion].Answers[i];
if(Qna[currentQuestion].CorrectAnswer == i + 1)
{
options[i].GetComponent<AnswerScript>().isCorrect = true;
}
}
}
void generateQuestion()
{
if(Qna.Count > 0)
{
currentQuestion = Random.Range(0, Qna.Count);
QuestionTxt.text = Qna[currentQuestion].Question;
SetAnswer();
}
else
{
Debug.Log("out of questions");
GameOver();
}
}
}
it is a quiz template but i doesn't work. does anyone know how to fix that?
i am a begginer in learning c#
When you define a question and answer:
public class QuestionAndANWSER
{
public Image[] Question;
public string[] Answers;
public int CorrectAnswer;
}
you are storing questions as IMAGES. Later, in generateQuestion(), you're trying to use the questions as TEXT:
void generateQuestion()
{
// ...
QuestionTxt.text = Qna[currentQuestion].Question;
// ...
}
You have to be consistent in how you're handling the questions. You either need to change the QuizManager to use an image for the QuestionTxt or you need to change QuestionAndANSWER to use text for the Question.

Unable to disable a collider

I am doing a dig the mud game. Have 2 mud gameobject(sprite) that need to dig in the correct order. I assign one script for each object. Disable mud2 boxcollider to prevent them from moving until mud 1 is drag to trigger L box collider . But when I try playing, mud2 still can be drag even though mud1 havent trigger L box collider. I also untick the box collider of mud2.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pg7_mud1 : MonoBehaviour
{
private Vector3 screenPoint;
private Vector3 startPosition;
public BoxCollider mud2;
// Start is called before the first frame update
void Start()
{
mud2.enabled = false;
}
// Update is called once per frame
void Update()
{
}
void OnMouseDown()
{
startPosition = this.gameObject.transform.position;
screenPoint = Camera.main.WorldToScreenPoint (gameObject.transform.position);
}
void OnMouseDrag()
{
Debug.Log("can drag");
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint);
this.transform.position = new Vector3(curPosition.x, -5f, curPosition.z);
}
void OnTriggerEnter(Collider other)
{
if(other.gameObject.name =="left-area")
{
Debug.Log("touched edge");
mud2.enabled = true;
}
}
You could try the Destroy(object, time) method instead of disabling colliders
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pg7_mud1 : MonoBehaviour
{
private Vector3 screenPoint;
private Vector3 startPosition;
public BoxCollider mud2;
public gameObject mud2obj;
// Start is called before the first frame update
void Start()
{
destroy(mud2);
}
// Update is called once per frame
void Update()
{
}
void OnMouseDown()
{
startPosition = this.gameObject.transform.position;
screenPoint = Camera.main.WorldToScreenPoint (gameObject.transform.position);
}
void OnMouseDrag()
{
Debug.Log("can drag");
Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint);
this.transform.position = new Vector3(curPosition.x, -5f, curPosition.z);
}
void OnTriggerEnter(Collider other)
{
if(other.gameObject.name =="left-area")
{
Debug.Log("touched edge");
mud2obj.AddComponent(typeof(BoxCollider));
}
}

Why is Xamarin.Android RecyclerView.Adapter not generic?

I have noticed the RecyclerView.Adapter type is not generic in Xamarin.Android. Why is it so? It seems to be defined as generic in native Android according to the documentation. Is there an underlying reason for this? Or is it some kind of backward compatiblity scenario?
You can create generic RecycleView in C# but not in java. In java you need to write code multiple times. That's why java android is worse even just simple event handler, Android Team Engineers are lazy to implements all data event handling because of the nature of java.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Util;
using Android.Views;
using Android.Widget;
namespace XamarinAndroid.Basic.Core
{
public class GenericRecyclerViewAdapter<T> : RecyclerView.Adapter
{
/// <summary>
/// You can set this for different custom cardview
/// </summary>
public int CardViewResourceLayout { get; set; }
public ObservableCollection<T> Items { get; private set; }
public event EventHandler<RecyclerViewViewHolder> ItemViewTemplated;
public GenericRecyclerViewAdapter(IEnumerable<T> items, int cardViewResourceLayout) : base()
{
this.Items = new ObservableCollection<T>(items);
this.CardViewResourceLayout = cardViewResourceLayout;
this.Items.CollectionChanged += (sender, e) =>
{
try
{
this.NotifyDataSetChanged();
}
catch { }
};
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemView = LayoutInflater.From(parent.Context).Inflate(CardViewResourceLayout, parent, false);
#if DEBUG
Log.Info("GenericRecyclerViewAdapter - ", CardViewResourceLayout.ToString());
#endif
RecyclerViewViewHolder vh = new RecyclerViewViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
RecyclerViewViewHolder vh = holder as RecyclerViewViewHolder;
vh.ItemPosition = position;
vh.TemplateView.Tag = position;
vh.TemplateView.Click -= TemplateView_Click;
vh.TemplateView.Click += TemplateView_Click;
this.ItemViewTemplated?.Invoke(this, vh);
}
public event EventHandler<T> ItemClicked;
private void TemplateView_Click(object sender, EventArgs e)
{
var position = (int)((View)sender).Tag;
this.ItemClicked?.Invoke(this, this.Items[position]);
}
public override int ItemCount
{
get { return this.Items.Count; }
}
public override long GetItemId(int position)
{
return base.GetItemId(position);
}
}
public class RecyclerViewViewHolder : RecyclerView.ViewHolder
{
public View TemplateView { get; private set; }
public int ItemPosition { get; set; }
public RecyclerViewViewHolder(View itemView) : base(itemView)
{
// Locate and cache view references:
this.TemplateView = itemView;
}
}
}
Assigning data to each view
var recyclerViewToday = this.FindViewById<Android.Support.V7.Widget.RecyclerView>(Resource.Id.recyclerViewToday);
var layoutManager = new LinearLayoutManager(this);
recyclerViewToday.SetLayoutManager(layoutManager);
var adapter = new GenericRecyclerViewAdapter<FavoriteModel>(previousList, Resource.Layout.recent_list_item);
adapter.ItemViewTemplated += (d, holder) =>
{
var indicate = holder.ItemView.FindViewById<View>(Resource.Id.indicatorItemmRec);
indicate.SetBackgroundColor(ColorHelper.GetRandomLightColor());
(holder.ItemView.FindViewById<TextView>(Resource.Id.wordTxtRec)).Text = adapter.Items[holder.ItemPosition].Word;
var textView = (holder.ItemView.FindViewById<TextView>(Resource.Id.definitionTxtRec));
if (!string.IsNullOrEmpty(previousList[holder.ItemPosition].Definition))
textView.Text = previousList[holder.ItemPosition].Definition;
else
textView.Visibility = Android.Views.ViewStates.Gone;
};
recyclerViewToday.SetAdapter(adapter);
Result
Clean, Generic and Reusable
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Support.V7.Widget;
using Android.Text;
using Android.Text.Style;
using Android.Util;
using Android.Views;
using Android.Widget;
using Java.Util.Zip;
using ActionMenuView = Android.Support.V7.Widget.ActionMenuView;
namespace Android.Basic.Core
{
public class GenericRecyclerViewAdapter<T> : RecyclerView.Adapter
{
/// <summary>
/// You can set this for different custom cardview
/// </summary>
private int CardViewResourceLayout { get; set; }
public ObservableCollection<T> Items { get; private set; }
public event EventHandler<RecyclerViewViewHolder> ItemViewTemplated;
public RecyclerView.LayoutManager layoutManager;
public GenericRecyclerViewAdapter(RecyclerView recyclerView, IEnumerable<T> items, int cardViewResourceLayout, bool isList = true, bool isVertical = true) : base()
{
if(isList)
{
var vertical = isVertical ? LinearLayoutManager.Vertical : LinearLayoutManager.Horizontal;
layoutManager = new LinearLayoutManager(recyclerView.Context, vertical, false);
}
else
{
var vertical = isVertical ? GridLayoutManager.Vertical : GridLayoutManager.Horizontal;
layoutManager = new GridLayoutManager(recyclerView.Context, 3, vertical, false);
}
recyclerView.SetLayoutManager(layoutManager);
this.Items = new ObservableCollection<T>(items);
this.CardViewResourceLayout = cardViewResourceLayout;
this.Items.CollectionChanged += delegate
{
this.NotifyDataSetChanged();
};
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemView = LayoutInflater.From(parent.Context).Inflate(CardViewResourceLayout, parent, false);
#if DEBUG
Log.Info("GenericRecyclerViewAdapter - ", CardViewResourceLayout.ToString());
#endif
RecyclerViewViewHolder vh = new RecyclerViewViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
RecyclerViewViewHolder vh = holder as RecyclerViewViewHolder;
vh.ItemPosition = position;
vh.TemplateView.Tag = position;
vh.TemplateView.Click -= TemplateView_Click;
vh.TemplateView.Click += TemplateView_Click;
ItemViewTemplated?.Invoke(this, vh);
}
public event EventHandler<T> ItemClicked;
private void TemplateView_Click(object sender, EventArgs e)
{
var position = (int)((View)sender).Tag;
this.ItemClicked?.Invoke(sender, this.Items[position]);
}
public override int ItemCount
{
get { return this.Items.Count; }
}
public override long GetItemId(int position)
{
return base.GetItemId(position);
}
}
public class RecyclerViewViewHolder : RecyclerView.ViewHolder, View.IOnCreateContextMenuListener,
IMenuItemOnMenuItemClickListener
{
public View TemplateView { get; private set; }
public int ItemPosition { get; set; }
public event EventHandler<MenuInfo> ContextMenuCreated;
public event EventHandler<object> MenuItemClicked;
public MenuInfo MenuInfo { get; private set; }
public object Data { get; set; }
public RecyclerViewViewHolder(View itemView) : base(itemView)
{
// Locate and cache view references:
this.TemplateView = itemView;
this.TemplateView.SetOnCreateContextMenuListener(this);
}
public void OnCreateContextMenu(IContextMenu menu, View v, IContextMenuContextMenuInfo menuInfo)
{
MenuInfo = new MenuInfo(menu, v, menuInfo);
ContextMenuCreated?.Invoke(this, MenuInfo);
}
private Android.Views.MenuInflater menuInflater = null;
/// <summary>
/// After ContextMenuCreated
/// </summary>
/// <param name="resourcemenu"></param>
public void InflateMenu(int resourcemenu, SpannableString titleColor = null, object dta = null)
{
if (dta != null)
this.Data = dta;
if (this.TemplateView.Context is AppCompatActivity activity)
{
menuInflater = activity.MenuInflater;
}
else if (this.TemplateView.Context is Activity activity2)
{
menuInflater = activity2.MenuInflater;
}
var contextMenu = this.MenuInfo.ContextMenu;
contextMenu.Clear();
menuInflater.Inflate(resourcemenu, contextMenu);
var num = contextMenu.Size() - 1;
for (int i = 0; i <= num; i++)
{
var men = contextMenu.GetItem(i);
if(titleColor != null)
{
if (i == 0)
{
men.SetTitle(titleColor);
men.SetChecked(true);
}
}
if (i != 0)
{
men.SetOnMenuItemClickListener(this);
}
}
}
public bool OnMenuItemClick(IMenuItem item)
{
this.MenuItemClicked?.Invoke(item, this.Data);
return true;
}
public float PosX;
public float PosY;
}
public class MenuInfo
{
public IContextMenu ContextMenu { get; }
public View View { get; }
public IContextMenuContextMenuInfo ContextMenuInfo { get; }
public MenuInfo(IContextMenu contextMenu, View view, IContextMenuContextMenuInfo menuInfo)
{
this.ContextMenu = contextMenu;
this.View = view;
this.ContextMenuInfo = menuInfo;
}
}
}
Usage
RecyclerView recyclerView = context.FindViewById<RecyclerView>(Resource.Id.recycler);
var viewAdapter = new Android.Basic.Core.GenericRecyclerViewAdapter<StorageFile>(recyclerView, files, Resource.Layout.main_item);
viewAdapter.ItemViewTemplated += (dd, holder) =>
{
//CardView
CardView cardView = holder.ItemView.FindViewById<CardView>(Resource.Id.CategorycardView);
cardView.SetCardBackgroundColor(ThemeHelper.IsDark ? Color.ParseColor("#303030") : Color.White);
var indicator = holder.ItemView.FindViewById<LinearLayout>(Resource.Id.indicator);
indicator.SetBackgroundColor(ThemeHelper.IsDark ? ColorHelper.GetRandomLightColor() : ColorHelper.GetRandomDarkColor());
var file = files[holder.ItemPosition];
var itemIcon = holder.ItemView.FindViewById<ImageView>(Resource.Id.itemIcon);
var icon = file.GetFileThumbnail();
if (icon != null)
{
itemIcon.SetImageBitmap(icon);
}
TextView itemName = holder.ItemView.FindViewById<TextView>(Resource.Id.itemName);
itemName.Text = file.DisplayName;
itemName.SetTextColor(textColor);
};
viewAdapter.ItemClicked += (dd, ff) =>
{
var checkBttn = (dd as View).FindViewById<ImageButton>(Resource.Id.check_boxBttn);
};
recyclerView.SetAdapter(viewAdapter);

Modify methods so they are given an array index value of the moon whose name or radius is required

So the part of my question is ''Modify getMoonName() and getMoonRadius() so they are given an array index value of the moon whose name or radius is required.''
I've tried adding moons[i].getRadius but then end up getting ''The variable i does not exist''. Here's the code.
PLANET CLASS
public class Planet
{
private float angle=0.01;
// add class member variables here
private String name;
private float radius;
private float distance;
private float speed;
private Moon[] moons;
// add constructor here
public Planet(String n, float r, float d, float s, Moon[] m)
{
this.name=n;
this.radius=r;
this.distance=d;
this.speed=s;
this.moons=m;
}
// add other methods here
public String getName()
{
return name;
}
public float getRadius()
{
return radius;
}
public float getDistance()
{
return distance;
}
public float getSpeed()
{
return speed;
}
public Moon[] getMoons()
{
return moons;
}
public void setRadius(float r)
{
this.radius=r;
}
public String getMoonName()
{
return moons[i].getName();
}
public float getMoonRadius()
{
return moons[i].getRadius();
}
public String toString()
{
int n=0;
for (int i=0; i<moons.length; i++)
{
n++;
}
return "Planet" + name + ("Radius: " +radius +"Distance: " +distance) +n +"moons.";
}
public void printMoons()
{
for (int i=0; i<moons.length; i++)
{
System.out.println(moons[i]);
}
}
// This will display the moon when other code is completed. You don't need to understand this code.
public void display()
{
angle=angle+(0.01*speed);
pushMatrix();
rotate(angle);
translate(distance,0);
fill(255, 255, 255);
ellipse(0, 0, radius*2, radius*2);
for(Moon moon: getMoons())
moon.display();
popMatrix();
}
}`
MOON CLASS
public class Moon
{
private float angle=0.01;
// add class member variables here
private String name;
private float radius;
private float distance;
private float speed;
private int orbitalPeriod;
// add constructor here
public Moon(String n, float r, float d, float s, int o)
{
this.name=n;
this.radius=r;
this.distance=d;
this.speed=s;
this.orbitalPeriod=o;
}
// add other methods here
public String getName()
{
return name;
}
public float getRadius()
{
return radius;
}
public float getDistance()
{
return distance;
}
public float getSpeed()
{
return speed;
}
public float getOrbitalPeriod()
{
return orbitalPeriod;
}
public void setName(String n)
{
this.name=n;
}
public void setOrbitalPeriod(int o)
{
this.orbitalPeriod=o;
}
public String toString()
{
return ("Moon : " +name +" "+"orbit="+orbitalPeriod);
}
// This will display the moon when other code is completed. You don't need to understand this code.
public void display()
{
angle=angle+(0.01*speed);
pushMatrix();
rotate(angle);
translate(distance, 0);
fill(149, 149, 149);
ellipse(0, 0, radius*2, radius*2);
popMatrix();
}
}
Let's look at this function:
public String getMoonName()
{
return moons[i].getName();
}
Where do you think the i variable is defined? Your instructions say to take an argument, but this function does not take any arguments.
As a small example, let's say I had this function:
public void printMessage(){
println("Hello!");
}
If I wanted to modify that function to take a parameter, I would have to add that to the method like this:
public void printMessage(String message){
println(message);
}
You have to do something similar with your getMoonName() function.
If you're still stuck, please post a small example like mine instead of your whole sketch, and we'll go from there.

Xamarin, Both ListView and RecyclerView, click one item, another one selected

I'm having a trouble with both ListView and RecyclerView
Initially, I created a ListView, everything is fine. Then I set onClick event for it so that every time I click an item, it changes its color to yellow. The OnClick function I wrote in the MainActivity. Problem is that when I test, not only that item changes its color but 2 items change. I read that it's because I reuse the view.
So I switch my tactics, using RecyclerView instead but same problem occurs. When I click one item to change its color, another below also changes. I guess it's because both ListView and RecyclerView reuse those Item so they confuse when I click one.
I don't know how to solve this problem, I found a solution is to add an array of boolean which marks which item is clicked but it doesn't work. Any idea guys?
So here is the code
MainActivity
class MainActivity : Activity
{
public RecyclerView recyclerView;
public RecyclerView.LayoutManager manager;
public RecyclerView.Adapter adapter;
List<Row> lst;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
init();
recyclerView = (RecyclerView)FindViewById(Resource.Id.recyclerView);
manager = new LinearLayoutManager(this);
recyclerView.SetLayoutManager(manager);
CustomAdapter adapter = new CustomAdapter(lst, this);
adapter.ItemClick += onItemClick;
recyclerView.SetAdapter(adapter);
}
public void init()
{
lst = new List<Row>();
for (int i = 0; i < 15; i++)
{
Row row = new Row() { field1="1:43:00", field2="09-Apr-16", field3="KPI/Overflow", field4="Kevin Bacon", field5="Unowned", field6= "People Counting # IPCAM-ID-C-1-1" };
lst.Add(row);
}
}
public void onItemClick(object sender, int position)
{
int itemPos = position + 1;
//Toast.MakeText(this, "this is " + itemPos, ToastLength.Short).Show();
recyclerView.GetChildAt(position).SetBackgroundColor(Android.Graphics.Color.Green);
}
}
Custom adapter
public class CustomAdapter : RecyclerView.Adapter
{
public Activity _activity;
public List<Row> lst;
public event EventHandler<int> ItemClick;
public CustomAdapter(List<Row> lst, Activity activity)
{
this.lst = lst;
this._activity = activity;
}
public override int ItemCount
{
get
{
return lst.Count;
}
}
public void OnClick(int position)
{
if (ItemClick!=null)
{
ItemClick(this, position);
}
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
MyViewHolder myholder = holder as MyViewHolder;
myholder.textView1.Text = lst[position].field1;
myholder.textView2.Text = lst[position].field2;
myholder.textView3.Text = lst[position].field3;
myholder.textView4.Text = lst[position].field4;
myholder.textView5.Text = lst[position].field5;
myholder.textView6.Text = lst[position].field6;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View v = this._activity.LayoutInflater.Inflate(Resource.Layout.item, parent, false);
TextView tv1 = (TextView)v.FindViewById(Resource.Id.textView1);
TextView tv2 = (TextView)v.FindViewById(Resource.Id.textView2);
TextView tv3 = (TextView)v.FindViewById(Resource.Id.textView3);
TextView tv4 = (TextView)v.FindViewById(Resource.Id.textView4);
TextView tv5 = (TextView)v.FindViewById(Resource.Id.textView5);
TextView tv6 = (TextView)v.FindViewById(Resource.Id.textView6);
MyViewHolder holder = new MyViewHolder(v, OnClick) { textView1 = tv1, textView2 = tv2, textView3 = tv3, textView4 = tv4, textView5 = tv5, textView6 = tv6 };
return holder;
}
}
class MyViewHolder : RecyclerView.ViewHolder
{
public TextView textView1, textView2, textView3, textView4, textView5, textView6;
public View mainView;
public MyViewHolder(View view, Action<int> listener) : base(view)
{
mainView = view;
mainView.Click += (sender, e) => listener(base.Position);
}
}
I followed the example for the OnClick handler on Xamarin site
https://developer.xamarin.com/guides/android/user_interface/recyclerview/
Your issue is with your code. You send the correct position to your event handler, but then you increment it by one in the Activity. Both ends should be using the 0-based index of the item position. There is no need to increment by one.
For changing the background color of the selected item, you can use a selector in XML so you wouldn't even need to do this in code.
Here is an example.
row_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#android:color/green" />
<item android:state_selected="false" android:color="#android:color/transparent"/>
</selector>
row_content.axml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/row_layout_parent"
android:background="#drawable/row_selector">
<!-- your row content -->
</LinearLayout>
Then your view holder would be updated to this...
class MyViewHolder : RecyclerView.ViewHolder
{
public TextView textView1, textView2, textView3, textView4, textView5, textView6;
public View mainView;
private LinearLayout _layoutParent;
public MyViewHolder(View view, Action<int> listener) : base(view)
{
mainView = view;
_layoutParent = mainView.FindViewById<LinearLayout>(Resource.Id.row_layout_parent);
_layoutParent.Click += (sender, e) => _layoutParent.Selected = true;
}
}
I removed the other click event. If you still need it for other reasons, then you can add it back, but it's not necessary for just setting the item background color when selected.
For Listview you should set choiceMode as below.
listView.ChoiceMode = ChoiceMode.Single;
Hope it help you :)-
Create a reusable recycleview adapter GENERIC
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Support.V7.Widget;
using Android.Text;
using Android.Text.Style;
using Android.Util;
using Android.Views;
using Android.Widget;
using Java.Util.Zip;
using ActionMenuView = Android.Support.V7.Widget.ActionMenuView;
namespace Android.Basic.Core
{
public class GenericRecyclerViewAdapter<T> : RecyclerView.Adapter
{
/// <summary>
/// You can set this for different custom cardview
/// </summary>
private int CardViewResourceLayout { get; set; }
public ObservableCollection<T> Items { get; private set; }
public event EventHandler<RecyclerViewViewHolder> ItemViewTemplated;
public RecyclerView.LayoutManager layoutManager;
public GenericRecyclerViewAdapter(RecyclerView recyclerView, IEnumerable<T> items, int cardViewResourceLayout, bool isList = true, bool isVertical = true) : base()
{
if(isList)
{
var vertical = isVertical ? LinearLayoutManager.Vertical : LinearLayoutManager.Horizontal;
layoutManager = new LinearLayoutManager(recyclerView.Context, vertical, false);
}
else
{
var vertical = isVertical ? GridLayoutManager.Vertical : GridLayoutManager.Horizontal;
layoutManager = new GridLayoutManager(recyclerView.Context, 3, vertical, false);
}
recyclerView.SetLayoutManager(layoutManager);
this.Items = new ObservableCollection<T>(items);
this.CardViewResourceLayout = cardViewResourceLayout;
this.Items.CollectionChanged += delegate
{
this.NotifyDataSetChanged();
};
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemView = LayoutInflater.From(parent.Context).Inflate(CardViewResourceLayout, parent, false);
#if DEBUG
Log.Info("GenericRecyclerViewAdapter - ", CardViewResourceLayout.ToString());
#endif
RecyclerViewViewHolder vh = new RecyclerViewViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
RecyclerViewViewHolder vh = holder as RecyclerViewViewHolder;
vh.ItemPosition = position;
vh.TemplateView.Tag = position;
vh.TemplateView.Click -= TemplateView_Click;
vh.TemplateView.Click += TemplateView_Click;
ItemViewTemplated?.Invoke(this, vh);
}
public event EventHandler<T> ItemClicked;
private void TemplateView_Click(object sender, EventArgs e)
{
var position = (int)((View)sender).Tag;
this.ItemClicked?.Invoke(sender, this.Items[position]);
}
public override int ItemCount
{
get { return this.Items.Count; }
}
public override long GetItemId(int position)
{
return base.GetItemId(position);
}
}
public class RecyclerViewViewHolder : RecyclerView.ViewHolder, View.IOnCreateContextMenuListener,
IMenuItemOnMenuItemClickListener
{
public View TemplateView { get; private set; }
public int ItemPosition { get; set; }
public event EventHandler<MenuInfo> ContextMenuCreated;
public event EventHandler<object> MenuItemClicked;
public MenuInfo MenuInfo { get; private set; }
public object Data { get; set; }
public RecyclerViewViewHolder(View itemView) : base(itemView)
{
// Locate and cache view references:
this.TemplateView = itemView;
this.TemplateView.SetOnCreateContextMenuListener(this);
}
public void OnCreateContextMenu(IContextMenu menu, View v, IContextMenuContextMenuInfo menuInfo)
{
MenuInfo = new MenuInfo(menu, v, menuInfo);
ContextMenuCreated?.Invoke(this, MenuInfo);
}
private Android.Views.MenuInflater menuInflater = null;
/// <summary>
/// After ContextMenuCreated
/// </summary>
/// <param name="resourcemenu"></param>
public void InflateMenu(int resourcemenu, SpannableString titleColor = null, object dta = null)
{
if (dta != null)
this.Data = dta;
if (this.TemplateView.Context is AppCompatActivity activity)
{
menuInflater = activity.MenuInflater;
}
else if (this.TemplateView.Context is Activity activity2)
{
menuInflater = activity2.MenuInflater;
}
var contextMenu = this.MenuInfo.ContextMenu;
contextMenu.Clear();
menuInflater.Inflate(resourcemenu, contextMenu);
var num = contextMenu.Size() - 1;
for (int i = 0; i <= num; i++)
{
var men = contextMenu.GetItem(i);
if(titleColor != null)
{
if (i == 0)
{
men.SetTitle(titleColor);
men.SetChecked(true);
}
}
if (i != 0)
{
men.SetOnMenuItemClickListener(this);
}
}
}
public bool OnMenuItemClick(IMenuItem item)
{
this.MenuItemClicked?.Invoke(item, this.Data);
return true;
}
public float PosX;
public float PosY;
}
public class MenuInfo
{
public IContextMenu ContextMenu { get; }
public View View { get; }
public IContextMenuContextMenuInfo ContextMenuInfo { get; }
public MenuInfo(IContextMenu contextMenu, View view, IContextMenuContextMenuInfo menuInfo)
{
this.ContextMenu = contextMenu;
this.View = view;
this.ContextMenuInfo = menuInfo;
}
}
}
Usage
RecyclerView recyclerView = new RecyclerView(this);
var viewAdapter = new Android.Basic.Core.GenericRecyclerViewAdapter<Java.IO.File>(recyclerView, files, Resource.Layout.directory_item);
var indiColor = ThemeHelper.IsDark ? ColorHelper.GetRandomLightColor() : ColorHelper.GetRandomDarkColor();
viewAdapter.ItemViewTemplated += (dd, holder) =>
{
var file = files[holder.ItemPosition];
var view = holder.ItemView;
var expanded = view.FindViewById<ExpandedView>(Resource.Id.expandedView);
expanded.SetToggleColor(indiColor);
expanded.SetTitle(file.Name);
GenerateRecycler(expanded, file);
};
recyclerView.SetAdapter(viewAdapter);
expandedView.AddExpandedView(recyclerView);

Resources