Different layouts on listview VS firebase constant updating - android

I'm trying to make a chat app out of a FireBase sample. I want to make it that when the same user sends a message twice there is no header on the second message. I made it so the header's size is 0dp if current user is the same as the last user, but when I scroll or even hide the keyboard the listview updates and messes it up (all headers dissappear). Can I make it check the element above or is there another way?
public class ChatListAdapter extends FirebaseListAdapter<Chat> {
// The mUsername for this client. We use this to indicate which messages originated from this user
private String mUsername;
private Typeface Consolas;
private String lastUsername = "";
public ChatListAdapter(Query ref, Activity activity, int layout, String mUsername) {
super(ref, Chat.class, layout, activity);
this.mUsername = mUsername;
this.Consolas = Typeface.createFromAsset(activity.getAssets(), "fonts/Consolas.ttf");
}
/**
* Bind an instance of the <code>Chat</code> class to our view. This method is called by <code>FirebaseListAdapter</code>
* when there is a data change, and we are given an instance of a View that corresponds to the layout that we passed
* to the constructor, as well as a single <code>Chat</code> instance that represents the current data to bind.
*
* #param view A view instance corresponding to the layout we passed to the constructor.
* #param chat An instance representing the current state of a chat message
*/
#Override
protected void populateView(View view, Chat chat) {
// Map a Chat object to an entry in our listview
String author = chat.getAuthor();
if (!author.equals(lastUsername)) {
TextView authorText = (TextView) view.findViewById(R.id.author);
authorText.setText(author);
// If the message was sent by this user, color it differently
if (author != null && author.equals(mUsername)) {
authorText.setTextColor(Color.RED);
} else {
authorText.setTextColor(Color.parseColor("#e4de33"));
}
authorText.setTypeface(Consolas);
TextView message = (TextView) view.findViewById(R.id.message);
message.setText(chat.getMessage());
message.setTextColor(Color.WHITE);
message.setTypeface(Consolas);
TextView date = (TextView) view.findViewById(R.id.date);
date.setText(chat.getDate());
date.setTextColor(Color.WHITE);
date.setTypeface(Consolas);
lastUsername = mUsername;
} else {
view.findViewById(R.id.divider).setLayoutParams(new LinearLayout.LayoutParams(0, 0));
view.findViewById(R.id.header).setLayoutParams(new LinearLayout.LayoutParams(0, 0));
TextView message = (TextView) view.findViewById(R.id.message);
message.setText(chat.getMessage());
message.setTextColor(Color.WHITE);
message.setTypeface(Consolas);
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/divider"
android:layout_height="1dp"
android:layout_width="fill_parent"
android:background="#color/background_darkblue"
android:orientation="horizontal" />
<LinearLayout
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="#dimen/avatar_size"
android:layout_height="#dimen/avatar_size"
android:padding="#dimen/avatar_padding"
android:src="#drawable/g"/>
<TextView
android:id="#+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
<TextView
android:id="#+id/date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/avatar_padding"
android:layout_marginRight="#dimen/avatar_padding"
android:layout_marginBottom="#dimen/avatar_padding" />
</LinearLayout>

Your code assumes that populateView() is called for each chat message in order. That is not necessarily the case, so you should come up with another way to find if the previous message is from the same user.
The FirebaseListAdapter.populateView() method now takes an extra parameter int position. With this parameter you an explicitly check whether the message before the current one is by the same user:
protected void populateView(View view, Chat chat, int position) {
String author = chat.getAuthor();
String previousAuthor = (position > 0) ? getItem(position-1).getAuthor();
if (!author.equals(previousAuthor)) {
...

So I fixed it by doing this:
String author = chat.getAuthor();
String previousAuthor = "";
int currentIndex = getmModels().indexOf(chat);
if (currentIndex > 0) {
Chat previousObject = (Chat) getItem(currentIndex - 1);
previousAuthor = previousObject.getAuthor();
}
And in the parent class I just had to create a getter for mModels. There was also another bug in this code with the layout changes because the adapter reused my changed params. The solution is to change params in both circumstances (same author and different author).

Related

Is it possible to use MutableLiveData with an array of object?

There's a fragment on the app I'm working on that the user needs to fill up to 6 EditText. Each pair of EditText represents the type and description of the user's address (as in "Apartment" as the Type and "1201" as the description). According to Brazil's postal service company, it is possible to add up to 3 complements.
At default, I'm showing one pair of EditText that represents the first complement. There's a button that let the user add two more address complements.
I want to use LiveData and DataBinding to update an array of Complements on my ViewModel but it isn't working and I have no idea why.
Is it possible to work with arrays and MutableLiveData?
XML
<android.support.design.widget.TextInputLayout
android:id="#+id/tipo1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView">
<android.support.design.widget.TextInputEditText
android:id="#+id/tipo1edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Tipo 1"
android:text="#={viewModel.complementoList.getValues().get(0).descricao}" />
</android.support.design.widget.TextInputLayout>
ViewModel
private MutableLiveData<ArrayList<Complemento>> complementoList;
public MutableLiveData<ArrayList<Complemento>> getComplementoList() {
if (complementoList == null) {
complementoList = new MutableLiveData<>();
ArrayList<Complemento> arrayComplemento = new ArrayList<>();
arrayComplemento.add(new Complemento());
arrayComplemento.add(new Complemento());
arrayComplemento.add(new Complemento());
complementoList.setValue(arrayComplemento);
}
return complementoList;
}
Fragment
final Observer<ArrayList<Complemento>> complementoList = new Observer<ArrayList<Complemento>>() {
#Override
public void onChanged(#Nullable ArrayList<Complemento> complementos) {
//update stuff here
}
};
mViewModel.getComplementoList().observe(this, complementoList);

Two way databinding with collection on Xamarin.Android/Android

I have a UI with some EditTexts in it and this set of edittexts can repeat number of times (not too much but 3 - 10 times max) based on the number of items in the list.
User can edit/modify/delete the item or edit the value of the edit texts. Currently I am doing this manually with "AddView/RemoveView", manually handling the states etc, however it is a lot of work as I have many scenarios like this.
We have a web app with the very same functionalities and we are using AngularJS to deal with all these, which, as you know is amazingly easy.
is there any closer way to bind the axml/xml view with a collection (may be an Observable collection and at least from the code behind) that will take care of collection changes as well as the individual field changes without me doing all this manually. In some scenarios I have to display images as well.
Also, I tried using a ListView, however it doesn't work as I would expect it to work.
is there any closer way to bind the axml/xml view with a collection (may be an Observable collection and at least from the code behind) that will take care of collection changes as well as the individual field changes without me doing all this manually.
The answer is no, there isn't. Android's views have to be bound to certain context/activity when they are created. They can't be isolated, so add/remove the EditTexts have to be implemented by yourself.
Currently, the closest way to your requirement is to create an ObservableCollection and listen for the CollectionChanged event and when CollectionChanged add/remove the view in your container:
[Activity(Label = "Demo", MainLauncher = true)]
public class MainActivity : Activity
{
Button btnAdd;
ObservableCollection<View> oc;
LinearLayout container;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
btnAdd = FindViewById<Button>(Resource.Id.btnAdd);
btnAdd.Click += BtnAdd_Click;
GenerateET(Resource.Id.container, this, 3);
}
private void BtnAdd_Click(object sender, System.EventArgs e)
{
EditText et = new EditText(this);
et.Text = "test";
et.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
oc.Add(et);
}
public void GenerateET(int resId, Activity activity,int num)
{
//create an observable collection
oc = new ObservableCollection<View>();
container = activity.FindViewById<LinearLayout>(resId);
for (int i = 0; i < num; i++)
{
EditText et = new EditText(activity);
et.Text = "test";
et.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
container.AddView(et);
oc.Add(et);
}
oc.CollectionChanged += Oc_CollectionChanged;
}
private void Oc_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
for (int i = 0; i < e.NewItems.Count; i++)
{
//add the view manually
container.AddView((View)e.NewItems[i]);
}
}
}
}
Main.axml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
<Button
android:id="#+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add EditText"/>
</LinearLayout>

android - some views are not "visible" after activity restart

Hello Android developers,
i'm facing a strange behaviour of some views after activity restart - there are some views, which are not "visible", but they are layouted and react on Touch actions.
I'm trying to keep the application follow Android lifetime guide. I drop the Activity to background and let system to close my activity. Then I navigate back to my activity, which is recreated. There is no problem with data to be corrupted (saved in db with every change made), but the views are. There are some properly shown, but everything inside TableView, which is inside ScrollView, is not visible. If I call getVisibility() on any of not shown views, i get that it is visible. As I mentioned above, views are not "visible", but react on Touch and scroll events, like they were properly shown.
This is also hard (impossible) to debug, cause when the app is closed, debbuger is disconnected. But anyway, recreation follows the same methods callback - onCreate(), onStart(), onResume(), so once created, why there's problem other time? The only difference to me is that there is a null Bundle in onCreate(Bundle) when Activity is newly created and not null when it is recreated by system. If the activity is only stopped (in background) but not closed by system, everything works fine.
I also tryed to override onSaveInstanceState() and onRestoreInstanceState() with nothing to be saved and restored (no call to super implementation), but it had no effect.
I'm using Android 4.1.1 and emulator 2.1.
Does anyone have any idea?
Thanks Ales
Here are (links to) screenshots to figure it out better:
Before activity is closed by system
After activity is recreated
Here are the layout files:
<!-- Header -->
<LinearLayout
android:id="#+id/startlistHeaderLayout" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView android:id="#+id/textStartlistName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
android:gravity="left"
android:text=""
/>
<TextView android:id="#+id/textStarttime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
android:gravity="right"
android:text=""
android:layout_weight="1"
/>
</LinearLayout>
<!-- Results -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#id/resultsScrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:saveEnabled="false"
>
<TableLayout
android:id="#id/timingLapTableLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="2"
android:shrinkColumns="2"
android:saveEnabled="false"
>
<!-- rows are added in code -->
</TableLayout>
</ScrollView>
</LinearLayout>
<!-- R.layout.timing_row -->
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#id/timingTableRow"
android:saveEnabled="false"
>
<TextView
android:id="#id/textTimingPosition"
android:text=""
android:gravity="right"
android:paddingLeft="4dip"
android:saveEnabled="false"
/>
<TextView
android:id="#id/textTimingBib"
android:text=""
android:gravity="right"
android:paddingLeft="1dip"
android:saveEnabled="false"
/>
<TextView
android:id="#id/textTimingName"
android:text=""
android:lines="1"
android:ellipsize="end"
android:gravity="left"
android:paddingLeft="1dip"
android:paddingRight="5dip"
android:saveEnabled="false"
/>
<TextView
android:id="#id/textTimingBehind1"
android:text=""
android:gravity="right"
android:paddingRight="5dip"
android:saveEnabled="false"
/>
<TextView
android:id="#id/textTimingBehind2"
android:text=""
android:gravity="right"
android:paddingRight="5dip"
android:saveEnabled="false"
/>
</TableRow>
Here is part of Activity code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
loadPreferencesTimingTheme();
if (ownTheme) {
this.setTheme(theme);
} else {
this.setTheme(MainActivity.theme);
}
}
protected void onStart() {
super.onStart();
View lapView;
View v;
int sid;
setContentView(R.layout.startlist_edit);
sid = getIntent().getIntExtra(TimingActivity.STARTLIST_ID, -1);
if (sid == -1) {
Toast.makeText(this, "Sorry, could not load startlist.", Toast.LENGTH_LONG);
this.finish();
return;
}
tdb = new TimingDB(this);
sl = tdb.getStartlist(sid); // get Startlist from db into memory
// hide unnecessary columns
v = findViewById(R.id.timingLapTableLayout);
((TableLayout) v).setColumnCollapsed(0, true);
loadStartlist(sl); // inflate rows with startlist data and set listeners
// load the preferences and set preferences listener
loadPreferences();
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(prefsChangeListener);
}
public void onStop() {
super.onStop();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(prefsChangeListener);
if (tdb != null) tdb.close();
}
protected void onSaveInstanceState (Bundle outState) {
// super.onSaveInstanceState(outState);
}
protected void onRestoreInstanceState (Bundle savedInstanceState) {
// super.onRestoreInstanceState(savedInstanceState);
}
protected void onDestroy() {
super.onDestroy();
if (tdb != null) tdb.close();
}
private void loadStartlist(StartList sl) {
// set startlist name & time
View v = findViewById(R.id.textStarttime);
((TextView) v).setText(SimpleDateFormats.ddmmyyyyhhmmss.format(new Date(sl.getStartTime())));
v = findViewById(R.id.textStartlistName);
((TextView) v).setText(sl.getName());
// set header onclicklistener
v = findViewById(R.id.startlistHeaderLayout);
v.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// show dialog to change startlist name and time
Bundle args = new Bundle();
args.putString(KEY_NAME, ((TextView) findViewById(R.id.textStartlistName)).getText().toString());
args.putString(KEY_STTIME, ((TextView) v.findViewById(R.id.textStarttime)).getText().toString());
if (Build.VERSION.SDK_INT < 8) {
dialogBundle = args;
showDialog(DIALOG_EDIT_STARTLIST);
} else {
showDialog(DIALOG_EDIT_STARTLIST, args);
}
}
});
// add competitors to startlist
int cnt = sl.getCompetitorsCount();
for (int i = 0; i < cnt; i++) {
Competitor c = sl.getCompetitorByIndex(i);
appendStartlistRow(c);
}
}
public void appendStartlistRow(final Competitor c) {
TableRow inflatedView = (TableRow) getLayoutInflater().inflate(R.layout.timing_row, null);
inflatedView.setTag(TAG_COMPETITOR, c);
inflatedView.setTag(new Integer(c.getBib()));
inflatedView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TableLayout tl = (TableLayout) findViewById(R.id.timingLapTableLayout);
Bundle args = new Bundle();
args.putInt(KEY_INDEX, tl.indexOfChild(v));
if (Build.VERSION.SDK_INT < 8) {
dialogBundle = args;
showDialog(DIALOG_EDIT_COMPETITOR);
} else {
showDialog(DIALOG_EDIT_COMPETITOR, args);
}
}
});
// set up texts
TextView text = (TextView) inflatedView.findViewById(R.id.textTimingBib);
text.setText(c.getBib() + "");
text = (TextView) inflatedView.findViewById(R.id.textTimingName);
text.setText(c.getName());
text = (TextView) inflatedView.findViewById(R.id.textTimingBehind1);
text.setText(getFormatedStartTime(sl, c, Settings.STARTTIME_ABSOLUTE));
text = (TextView) inflatedView.findViewById(R.id.textTimingBehind2);
text.setText(getFormatedStartTime(sl, c, Settings.STARTTIME_RELATIVE));
// append the row
appendStartlistRow((ViewGroup) inflatedView);
}
public void appendStartlistRow(ViewGroup row) {
// set background and text colors
if (((((Integer) row.getTag()).intValue()) % 2) == Defs.VIEW_EVEN) {
row.setBackgroundColor(Defs.COLOR_BACKGROUND_EVEN);
for (int j = 0; j < row.getChildCount(); j++) {
((TextView) (row.getChildAt(j))).setTextColor(Defs.COLOR_TEXT_EVEN);
}
} else {
row.setBackgroundColor(Defs.COLOR_BACKGROUND_ODD);
for (int j = 0; j < row.getChildCount(); j++) {
((TextView) (row.getChildAt(j))).setTextColor(Defs.COLOR_TEXT_ODD);
}
}
((TableLayout) findViewById(R.id.timingLapTableLayout)).addView(row);
}
Defs.java:
public class Defs {
protected static final int VIEW_EVEN = 0;
protected static final int VIEW_ODD = 1;
protected static int COLOR_BACKGROUND_EVEN;
protected static int COLOR_BACKGROUND_ODD;
protected static int COLOR_BACKGROUND_SELECTED;
protected static int COLOR_BACKGROUND_SPYED;
protected static int COLOR_TEXT_ODD;
protected static int COLOR_TEXT_EVEN;
protected static int COLOR_TEXT_SELECTED;
protected static int COLOR_TEXT_SPYED;
private static boolean isInitialized = false;
protected static void init(Context c) {
if (isInitialized) return;
COLOR_BACKGROUND_EVEN = c.getResources().getColor(R.color.background_darker);
COLOR_BACKGROUND_ODD = c.getResources().getColor(R.color.background_lighter);
COLOR_BACKGROUND_SELECTED = c.getResources().getColor(R.color.background_selected);
COLOR_BACKGROUND_SPYED = c.getResources().getColor(R.color.background_spyed);
COLOR_TEXT_ODD = c.getResources().getColor(R.color.text_lighter);
COLOR_TEXT_EVEN = c.getResources().getColor(R.color.text_darker);
COLOR_TEXT_SELECTED = c.getResources().getColor(R.color.text_selected);
COLOR_TEXT_SPYED = c.getResources().getColor(R.color.text_spyed);
isInitialized = true;
}
}
Without any code it's next to impossible to say much about the problem itself. But I did want to say (would fit better as a comment but can't do it yet) that for a long list (like yours seems to be based on the screenshots) using an actual ListView with a custom ArrayAdapter might be a better solution. ListView re-uses views when scrolled thus reducing unnecessary view creation. Also, once you learn how to use the ListView, you'll probably find it easier than adding table rows manually. If those aren't familiar to you, check a tutorial here:
http://www.vogella.com/articles/AndroidListView/article.html
And if you decide to change from tables to a ListView, maybe the problem (whatever it is) disappears as well. You never know. :)

click link in textview

I have text view and I want to set-text as link to direct the site but
the problem is that I cannot click:
Grades = (TextView) findViewById(R.id.textView9);
Grades.setText(Html.fromHtml(course.getString(TAG_Grade)));
Grades.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
WebView webView; webView.setWebViewClient(new WebViewClient()
{
}webView.loadUrl(course.getString(TAG_Grade)); });
And the xml:
<TextView
android:id="#+id/textView9"
android:layout_marginLeft="110dp"
android:layout_marginTop="365dp"
android:textColor="#000"
android:textSize="14sp"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:autoLink="web"
android:onClick="onClick"
/>
Knowing that course.getString(TAG_Grade) will get the url from db but it does not work
What is the problem?
You are trying to Linkify it after the view is clicked, removed the Linkify from within the onClick.
Your going about it the wrong way.
Try this:
String userCanSeeThis = "Your Website Name";
String url = course.getString(TAG_Grade);
TextView grades = (TextView) findViewById(R.id.textView9);
grades.setText(userCanSeeThis);
addLinks(Grades, userCanSeeThis, url);
Using this helper method:
/**
* #param textView
* textView who's text you want to change
* #param linkThis
* a regex of what text to turn into a link
* #param toThis
* the url you want to send them to
*/
public static void addLinks(TextView textView, String linkThis, String toThis) {
Pattern pattern = Pattern.compile(linkThis);
String scheme = toThis;
android.text.util.Linkify.addLinks(textView, pattern, scheme, new MatchFilter() {
#Override
public boolean acceptMatch(CharSequence s, int start, int end) {
return true;
}
}, new TransformFilter() {
#Override
public String transformUrl(Matcher match, String url) {
return "";
}
});
}
Also if you set the onClickListener in your code with grades.setOnClickListener then your don't need android:onClick="" in your XML
Used this android:clickable="true"
<TextView
android:id="#+id/textView9"
android:layout_marginLeft="110dp"
android:layout_marginTop="365dp"
android:textColor="#000"
android:textSize="14sp"
android:clickable="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:autoLink="web"
android:onClick="onClick"
/>
Instead of using Linkify i would prefer the below line:
Html.fromHtml(course.getString(TAG_Grade));
TextView myWebSite = new TextView(this);
myWebSite .setText("http://www.google.com/");
Linkify.addLinks(myWebSite , Linkify.WEB_URLS);
You have received enough answers regarding Linkify, but there is one more subtile error crawling in your code:
You are mistaking the attribute his android:onClick with the method onClick of an View.onClickListener:
The attribute android:onClick works as followed:
Name of the method in this View's context to invoke when the view is
clicked. This name must correspond to a public method that takes
exactly one parameter of type View. For instance, if you specify
android:onClick="sayHello", you must declare a public void
sayHello(View v) method of your context (typically, your Activity).
As for the onClick-method provided by the View.onClickListener-interface:
view.setOnClickListener(...)
Register a callback to be invoked when this view is
clicked. If this view is not clickable, it becomes clickable.
Which will allow you to override the function :
public abstract void onClick (View v)
which is called when a view has been clicked.

how to get R.id's in the int array?

I want to get the id's of my imageviews in my ObjectsClass which are in level1.xml and I have inflated this layout in GamePlayActivity...MY ObjectClass is not activity then how to get array of id's in that class ...here is my level.xml say there are 15 ImageView I have just shown few ....
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/gmw_01"
android:onClick="onClick"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/relativeLayout1" >
<ImageView
android:onClick="objectClick"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/imageView1"
android:src="#drawable/bb01"
android:layout_marginLeft="998dp"
android:layout_marginTop="593dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
<ImageView
android:onClick="objectClick"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/imageView2"
android:src="#drawable/bb02"
android:layout_marginLeft="20dp"
android:layout_marginTop="39dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
<ImageView
android:onClick="objectClick"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/imageView3"
android:src="#drawable/bb03"
android:layout_marginLeft="497dp"
android:layout_marginTop="153dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
and here is my GameplayActivity
public class GamePlayActivity extends Activity {
static int ObjectsFound;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameplay);
// ViewGroup where n number of view is going to added
ViewGroup layout= (ViewGroup) findViewById(R.id.GamePlayScreen);
// inflating the layout depending on the level
View level = View.inflate(this, LevelSelectionActivity.levelscreen, null);
** getRandom(); // here I want to call that random because this should be done before my level is added on the view**
// adding level bg for the respective selected level
layout.addView(level);
}
public void objectClick(View objectClicked)
{
Toast msg;
int Object = objectClicked.getId();
ImageView img= (ImageView)findViewById(objectClicked.getId());
switch (Object) {
case R.id.imageView1:
img.setVisibility(View.INVISIBLE);
msg = Toast.makeText(GamePlayActivity.this, "Bubble Found", Toast.LENGTH_SHORT);
msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2, msg.getYOffset() / 2);
msg.show();
break;
}
}
and the ObjectClass
public class Objects {
int ObectId[];
Objects(Context context)
{
super();
for(int i=0;i<15;++i)
{
**ObectId[i]=R.id.;** // what to get it over here ? ? ?
}
}
public void randomize() {
Random generator = new Random();
for(int i = 0; i<8 ; i++) {
while(true) {
**View v = findViewById(generator.nextInt(Objectid.length));**
if(!v.isClickable()) {
v.setClickable(false);
break;
}
}
}
}
}
at the end I want random number of objects to be unclickable i.e. out of 15 objects everytime user can have only 8 objects clickable on the screen so before my level starts i.e. before I inflate in my gameplayActivity as seen above I want to get random 8 clickable and vice versa...
Adding to that it should work for all level ...right now I have one level1.xml how to achieve it for all levels... do i need to give same id's of image view in all layout ?
Sure you can, all you need to do is make the ImageView with the same id name, then you can always access them with the same int id.
Don't forget to re-init them after load new layout.
try some thing like this
int resA = getResources().getIdentifier("your image view", "your layout", getPackageName());
hope this help..
Are there any views inside that RelativeLayout besides each ImageView you're interested in? If not, just use the getChildCount() and getChildAt() methods on the layout to obtain the views you need. Any ViewGroup already stores its children in an array, so there's no reason to duplicate the behavior if those are the only views contained there:
//Somewhere in your code get a reference to the layout
RelativeLayout layout = (RelativeLayout)findViewById(R.id.relativeLayout1);
//Then, update your view selection line like so
**View v = layout.getChildAt(generator.nextInt(layout.getChildCount()));**
HTH

Categories

Resources