I have a BaseAdapter with 3 kind of layout which is used to put JSONObject to my ListView. The adapter getCount() returns correct number of items that should be displayed on the ListView, but it only display the first one.
I tried to find another response to this problem here, but i've found none.
This is my code:
public class PerfilInfoAdapter extends BaseAdapter {
public static final int VIEW_TYPE_TITULO = 0;
public static final int VIEW_TYPE_DESCRICAO = 1;
public static final int VIEW_TYPE_KEY_VALUE = 2;
private JSONArray list;
private Activity activity;
private ViewHolder viewHolder;
public PerfilInfoAdapter(Activity activity, JSONArray list) {
this.activity = activity;
this.list = list;
}
protected class ViewHolder {
TextView textViewTitulo;
TextView textViewDescricao;
TextView textViewKey;
TextView textViewValue;
}
#Override
public int getCount() {
Log.d("PerfilInfoAdapter", "Number of items in array: " + Integer.toString(this.list.length()));
return this.list.length();
}
#Override
public JSONObject getItem(int position) {
JSONObject json = null;
try {
json = this.list.getJSONObject(position);
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
int retorno = -1;
JSONObject json = null;
try {
json = this.list.getJSONObject(position);
if (json.getString("key").equals("Titulo")) {
retorno = VIEW_TYPE_TITULO;
} else if (json.getString("key").equals("Descrição")
|| json.getString("key").equals("Sou")) {
retorno = VIEW_TYPE_DESCRICAO;
} else {
retorno = VIEW_TYPE_KEY_VALUE;
}
} catch (JSONException e) {
e.printStackTrace();
}
return retorno;
}
#Override
public int getViewTypeCount() {
return 3;
}
#Override
public View getView(int position, View container, ViewGroup viewGroup) {
System.out.println("getView " + position + " " + container);
this.viewHolder = null;
int type = this.getItemViewType(position);
if (container == null) {
this.viewHolder = new ViewHolder();
switch (type) {
case VIEW_TYPE_TITULO:
container = this.activity.getLayoutInflater().inflate(
R.layout.perfil_info_full_titulo, viewGroup, false);
this.viewHolder.textViewTitulo = (TextView) container
.findViewById(R.id.perfil_info_full_textViewTitulo);
break;
case VIEW_TYPE_DESCRICAO:
container = this.activity.getLayoutInflater().inflate(
R.layout.perfil_info_full_descricao, viewGroup, false);
this.viewHolder.textViewDescricao = (TextView) container
.findViewById(R.id.perfil_info_full_textVewDescricao);
break;
case VIEW_TYPE_KEY_VALUE:
container = this.activity.getLayoutInflater().inflate(
R.layout.perfil_info_list, viewGroup, false);
this.viewHolder.textViewKey = (TextView) container
.findViewById(R.id.perfil_info_full_chave_valor_textFieldChave);
this.viewHolder.textViewValue = (TextView) container
.findViewById(R.id.perfil_info_full_chave_valor_textFieldValor);
break;
}
container.setTag(this.viewHolder);
} else {
this.viewHolder = (ViewHolder)container.getTag();
}
try {
JSONObject json = this.list.getJSONObject(position);
switch (type) {
case VIEW_TYPE_TITULO:
this.viewHolder.textViewTitulo.setText(json.getString("value"));
break;
case VIEW_TYPE_DESCRICAO:
this.viewHolder.textViewDescricao.setText(json
.getString("value"));
break;
case VIEW_TYPE_KEY_VALUE:
this.viewHolder.textViewKey.setText(json.getString("key"));
this.viewHolder.textViewValue.setText(json.getString("value"));
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
return container;
}
}
This is what my log returns:
10-26 09:42:30.568: D/PerfilInfoAdapter(17228): Number of items in
array: 11
Another important information is that my ListView is inside another GridView, which has 4 different kinds of views, the gridView is working perfectly, but not the ListView.
public class PerfilAdapter extends BaseAdapter {
private List<JSONObject> jsonList;
private Activity activity;
private PerfilHelper helper;
private ImageLoader imageLoader;
private ViewHolder viewHolder;
private boolean exibirFull;
public static final int VIEW_TYPE_FOTO_PRINCIPAL = 0;
public static final int VIEW_TYPE_INFO = 1;
public static final int VIEW_TYPE_INFO_LIST = 2;
public static final int VIEW_TYPE_GALERIA = 3;
public PerfilAdapter(Activity activity, List<JSONObject> json, PerfilHelper helper) {
this.activity = activity;
this.helper = helper;
this.jsonList = json;
this.exibirFull = true;
if (!ImageLoader.getInstance().isInited()) {
ImageLoader.getInstance().init(new ImageLoaderConfiguration.Builder(this.activity).build());
}
imageLoader = ImageLoader.getInstance();
}
public void exibirFull(boolean exibir) {
this.exibirFull = exibir;
this.notifyDataSetChanged();
}
#Override
public int getCount() {
return this.jsonList.size();
}
#Override
public Object getItem(int i) {
return this.jsonList.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public int getItemViewType(int position) {
int retorno = -1;
if (this.jsonList.get(0).has("foto")) {
if (position == 0) {
retorno = VIEW_TYPE_FOTO_PRINCIPAL;
}
else if (position == 1) {
retorno = VIEW_TYPE_INFO;
}
else if (position == 2) {
if (this.exibirFull) {
retorno = VIEW_TYPE_INFO_LIST;
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
else {
if (position == 0) {
retorno = VIEW_TYPE_INFO;
}
else if (position == 1) {
if (this.exibirFull) {
retorno = VIEW_TYPE_INFO_LIST;
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
return retorno;
}
#Override
public int getViewTypeCount() {
return 4;
}
public void updateJsonPerfil(List<JSONObject> json) {
this.jsonList = json;
this.notifyDataSetChanged();
}
#Override
public View getView(int i, View container, ViewGroup viewGroup) {
this.viewHolder = null;
int type = this.getItemViewType(i);
if (container == null) {
this.viewHolder = new ViewHolder();
switch (type) {
case VIEW_TYPE_FOTO_PRINCIPAL:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_foto, viewGroup, false);
this.viewHolder.imageView = (ImageView) container.findViewById(R.id.perfil_foto_imageView);
break;
case VIEW_TYPE_INFO:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_info, viewGroup, false);
this.viewHolder.textViewApelido = (TextView) container.findViewById(R.id.perfil_info_apelido);
this.viewHolder.textViewCidade = (TextView) container.findViewById(R.id.perfil_info_textVewCidade);
this.viewHolder.textViewDistancia = (TextView) container.findViewById(R.id.perfil_info_textViewDistancia);
break;
case VIEW_TYPE_INFO_LIST:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_info_list, viewGroup, false);
this.viewHolder.listViewInfo = (ListView) container.findViewById(R.id.perfil_info_list_listView);
break;
case VIEW_TYPE_GALERIA:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_info, viewGroup, false);
break;
}
container.setTag(this.viewHolder);
}
else {
this.viewHolder = (ViewHolder)container.getTag();
}
if (this.jsonList.size() > 0) {
JSONObject json = this.jsonList.get(i);
try {
if (type == VIEW_TYPE_FOTO_PRINCIPAL) {
JSONObject foto = json.getJSONObject("foto");
this.imageLoader.displayImage(foto.getString("full"), this.viewHolder.imageView);
}
else if (type == VIEW_TYPE_INFO) {
JSONObject perfil = json.getJSONObject("perfil");
this.viewHolder.textViewApelido.setText(perfil.getString("apelido"));
this.viewHolder.textViewCidade.setText(perfil.getString("cidade"));
this.viewHolder.textViewDistancia.setText(perfil.getString("distancia"));
}
else if (type == VIEW_TYPE_INFO_LIST) {
// This is where i use the second ListView
this.viewHolder.listViewInfo.setAdapter(new PerfilInfoAdapter(this.activity, json.getJSONArray("info")));
}
else {
Log.d("PerfilAdapter", "Populando: VIEW_TYPE_GALERIA");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return container;
}
protected class ViewHolder {
ImageView imageView;
TextView textViewApelido;
TextView textViewCidade;
TextView textViewDistancia;
ListView listViewInfo;
}
}
I have tried changing the ListView to a GridView, but the problem is with the adapter.
Can anybody help me? I would appreciate it!
Your first problem: Trying to combine a ListView and a GridView. Never ever ever put one within the other. You'll have all sorts of problems...as you are noticing. The first big problem is scrolling. Android does not like it when a scrollable view is embedded within another and both scroll the same direction. Comical sketch from Android employee about this. Doing so is only viable when one scrolls horizontally and the other vertically.
Your next big problem, embedding a ListAdapter within another ListAdapter. You have to remember, that the getView() method can be invoked 3-4 times per position. When you embed another adapter for each position which itself will be invoked 3-4 times per it's own position...holy performance hit! This has bad idea written all over it.
A concern I see is your JSONArray/List referencing. The PerfilInfoAdapter maintains the same reference to the JSONArray used to instantiate it...which is the same data referenced by the PerfilAdapter List. Further the PerfilAdapter maintains the same list referenced by whomever is using it. This sets up a dangerous chain of references that can cause issues when modifying if you are not careful. Ideally, each adapter should maintain the same data in its on List or JSONArray instance.
To sum up, the answer is to change your design choice. There are other ways to display data other then needing vertical scrolling within vertical scrolling. If the ListView doesn't need scrolling use a LinearLayout. If the GridView doesn't need scrolling use a TableLayout or GridLayout. Or just completely change the UX by coming up with a different UI.
As a side note, if you need a full fledged JSONArray adapter check out Advanced-Adapters. The JSONAdapter is releasing within a week or so and can be found on the Redesign branch. Its code complete, just the demo app that's holding up the release.
How about implement getItem correctly (not return null)?
or I prefer
make POJO class and convert JSON into it. (like using GSON)
extends ArrayAdapter instead of BaseAdapter so that u don't have to implements all abstract methods.
Related
I have a listview and a button in my main activity and three layout ressource files (right.xml, mid.xml and left.xml [They're relative layout]).
I want to make an arrayList (with strings and drawable (images)) and each time I push the button in main.xml the first content of the arrayList will appear at the bottom of the screen (either left, mid or right --> depend of the order of the arrayList) and when I click again the next item (string or drawable) will appear beneath it, pushing it in an upward motion.
UPDATE
I made a Model and an Adapter
Here is the model
public class ModelC1 {
public String C1Name;
public String C1Text;
public int id;
public boolean isSend;
public ModelC1(String C1Name, String C1Text, int id, boolean isSend){
this.id = id;
this.C1Name = C1Name;
this.C1Text = C1Text;
this.isSend = isSend;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getC1Name() {
return C1Name;
}
public void setC1Name(String C1Name){
this.C1Name = C1Name;
}
public String getC1Text() {
return C1Text;
}
public void setC1Text (String C1Text){
this.C1Text = C1Text ;
}
public boolean isSend() {
return isSend;
}
public void setIsSend(boolean send){
isSend = send;
}
Here is the Adapter
public class AdapterC1 extends BaseAdapter {
private List<ModelC1> listChat;
private LayoutInflater inflater;
private Context context;
public AdapterC1(List<ModelC1> listChat, Context context){
this.listChat = listChat;
this.context = context;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listChat.size();
}
#Override
public Object getItem(int i) {
return listChat.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View vi = convertView;
if(convertView == null ){
if(listChat.get(i).isSend() == 0)
vi=inflater.inflate(R.layout.list_send,null);
else if ((listChat.get(i).isSend() == 1))
vi=inflater.inflate(R.layout.list_recv,null);
else if ((listChat.get(i).isSend() == 2))
vi=inflater.inflate(R.layout.list_mid,null);
}else{
if(listChat.get(i).isSend() == 0)
vi=inflater.inflate(R.layout.list_send,null);
else if ((listChat.get(i).isSend() == 1))
vi=inflater.inflate(R.layout.list_recv,null);
else if ((listChat.get(i).isSend() == 2))
vi=inflater.inflate(R.layout.list_mid,null);
}
if(listChat.get(i).isSend() !=0 || listChat.get(i).isSend() !=1 || listChat.get(i).isSend() !=2 ){
BubbleTextView bubbleTextView = (BubbleTextView) vi.findViewById(R.id.bubbleChat);
if(bubbleTextView != null)
bubbleTextView.setText(listChat.get(i).C1Text);
TextView nameTextView = (TextView) vi.findViewById(R.id.nameChat);
if(nameTextView != null)
nameTextView.setText(listChat.get(i).C1Name);
}else{
vi=inflater.inflate(R.layout.list_mid,null);
BubbleTextView bubbleTextView = (BubbleTextView) vi.findViewById(R.id.bubbleChat);
bubbleTextView.setText("THE END");
}
return vi;
}
And here is the activity
public class Chat1 extends AppCompatActivity {
private static final String TAG = "Chat1";
private AdapterC1 adapter;
private List<ModelC1> listChat = new ArrayList<>();
private int count = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat1);
RecyclerView chatContent1 = findViewById(R.id.chatContent1);
}
private ModelC1 setUpMessage(){
Log.d(TAG, "setUpMessage: Exec");
return();
}
///OnClick of the button in the activity_chat1.xml
public void nextClicked1(View view) {
Log.d(TAG, "nextClicked: Is Clicked");
///After the limit of the arraylist is reached
final int limit = 40;
if(count == limit){
Log.d(TAG, "nextClicked: Limit Reached");
Intent i = new Intent(Chat1.this, MainActivity.class);
startActivity(i);
}else{
///Call the list
loadList(null);
}
}
///Load the list of arrays?
public void loadList(View view){
ModelC1 chat = setUpMessage();
listChat.add(chat);
///The ID of the recycleview in the activity_chat1.xml
final RecyclerView recyclerview = findViewById(R.id.chatContent1);
///The adapter
final AdapterC1 adapter = new AdapterC1(listChat, this);
///Make the recyclerview always scroll
///the adapter
///recyclerview.setAdapter(adapter);
}
My questions are now how do I make the ArrayList (containing strings and drawables) and how to link the ArrayList to make it appear one by one when I click on the button ?
As for the ArrayList, will soemthing like that works ?
private List<List<String>> textChat1 = new ArrayList<List<String>>();
ArrayList<String> textChat1 = new ArrayList<String>();
textChat1.add("This is message 1");
textChat1.add("This is message 2");
textChat1.add("This is message 2");
addresses.add(textChat1);
How can I add images and how to say which strings inflate which layout (left, mid or right) ?
You can do your job like this: in your Adapter's getView method ,
#Override
public View getView(int position, View convertView, ViewGroup container) {
if (convertView == null) {
if (position == 1) {
convertView = getLayoutInflater().inflate(R.layout.left, container, false);
} else if (position == 2) {
convertView = getLayoutInflater().inflate(R.layout.mid, container, false);
} else {
convertView = getLayoutInflater().inflate(R.layout.right, container, false);
}
}
//your code here
return convertView;
}
This will do your job, but, I suggest you to use Recyclerview because it's more efficient and better in terms of looks as well as memory management.
I am trying to make an application with a ListView that include a Country Flag and name. This is so that the user can click on them and be shown images of the country that they wouldve taken before. However for about 3 seconds when the listview loads if i try to scroll it will sort of glitch and send me back to top. This is the code..
public class CountriesListAdapter extends ArrayAdapter {
private int resource;
private LayoutInflater inflater;
private List<CountryModel> countryModels;
private WeakReference<TextView> selectedCountryIdtxt;
private boolean useFilter;
private WeakReference<ProgressBar> progressBarWeakReference;
public int getSelectedCountryId() {
return selectedCountryId;
}
public void setSelectedCountryId(int selectedCountryId) {
this.selectedCountryId = selectedCountryId;
}
private int selectedCountryId;
public CountriesListAdapter(#NonNull WeakReference<Context> context, int resourceId, WeakReference<TextView> textView, #NonNull List<CountryModel> countryModelList, boolean useFilter, WeakReference<ProgressBar> progressBarWeakReference){
super(context.get(), resourceId, countryModelList);
selectedCountryIdtxt = textView;
resource = resourceId; //the id of the template file
inflater = LayoutInflater.from(context.get());
this.countryModels = countryModelList;
selectedCountryId = -1;
this.useFilter = useFilter;
this.progressBarWeakReference = progressBarWeakReference;
}
public int getCount() {
if (countryModels != null)
return countryModels.size();
return 0;
}
public CountryModel getItem(int position) {
if (countryModels != null)
return countryModels.get(position);
return null;
}
public long getItemId(int position) {
if (countryModels != null)
return countryModels.get(position).hashCode();
return 0;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// this method is automatically called for every object in our list
//basically it's called for every single row before it is generated
// this method is called per row
convertView = (ConstraintLayout) inflater.inflate(resource, null);
//the variable countryModel is fiiled with current object that is being processed
final CountryModel countryModel = countryModels.get(position);
TextView countryName = convertView.findViewById(R.id.countryNamelbl);
final ImageView countryFlag = convertView.findViewById(R.id.countryFlagimg);
final ImageView checked = convertView.findViewById(R.id.countryCheckedimg);
//this is done for every object in the list
assert countryModel != null;
countryName.setText(countryModel.getName());
Picasso.get().load(countryModel.getImage()).fit().into(countryFlag);
if(!useFilter) {
if (selectedCountryId == countryModel.getId()) {
checked.setVisibility(View.VISIBLE);
} else {
checked.setVisibility(View.INVISIBLE);
}
}
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!useFilter) {
if (checked.getVisibility() == View.VISIBLE) {
checked.setVisibility(View.INVISIBLE);
selectedCountryId = -1;
selectedCountryIdtxt.get().setText(String.valueOf(selectedCountryId));
} else {
if (selectedCountryId == -1) {
checked.setVisibility(View.VISIBLE);
selectedCountryId = countryModel.getId();
} else {
selectedCountryId = countryModel.getId();
notifyDataSetChanged();
}
selectedCountryIdtxt.get().setText(String.valueOf(selectedCountryId));
}
} else {
Intent i = new Intent(getContext(), PicturesActivity.class);
i.putExtra("countryId",countryModel.getId());
i.putExtra("countryName", countryModel.getName());
getContext().startActivity(i);
}
}
});
progressBarWeakReference.get().setVisibility(View.INVISIBLE);
return convertView;
}
public List<CountryModel> getCountryModels() {
return countryModels;
}
public void setCountryModels(List<CountryModel> countryModels) {
this.countryModels = countryModels;
}
}
The problem was actually in another class, i was calling the adapter for every list item instead of just once... oops.
Thanks for the replies though!
I have a problem to how can I display a different xml layout for a modified list view.
My list view acts as a comment section.
I just want to display a edit and delete button for the owner of that certain comment and display nothing at all if he/she is not the owner of it.
this is my sample code
btw I am using json
protected void onPostExecute(JSONObject json) {
HashMap<String, String> user = session.sessionGetIdAccountType();
String session_user_id = user.get(UserSessionManager.KEY_ID);
int integer_session_user_id = Integer.parseInt(session_user_id);
String user_id = "";
boolean usercomment = false;
try {
commentData = json.getJSONArray("list");
for (int i = 0; i < commentData.length(); i++) {
JSONObject source = commentData.getJSONObject(i);
Commenters commenter = new Commenters();
commenter.setName(source.getString("User_Fname") + " "
+ source.getString("User_Lname"));
commenter.setDate(source.getString("Comment_Date"));
commenter.setUsername(source.getString("User_Username"));
commenter.setComment(source.getString("Comment_Content"));
int integer_user_id = Integer.parseInt(user_id = source
.getString("User_ID"));
commenterList.add(commenter);
ListView listview = (ListView) findViewById(R.id.comment_list);
if (integer_session_user_id == integer_user_id) {
usercomment = true;
} else {
usercomment = false;
}
if (usercomment) {
adapter2 = new CommenterAdapter2(
getApplicationContext(), R.layout.row_user,
commenterList);
listview.setAdapter(adapter2);
} else {
adapter = new CommenterAdapter(getApplicationContext(),
R.layout.row, commenterList);
listview.setAdapter(adapter);
}
}
}
catch (Exception e) {
e.fillInStackTrace();
}
}
Hope this might help you.
public class TestListViewAdapter extends ArrayAdapter<Object> {
static final int TYPE_HEADER = 0;
static final int TYPE_CELL = 1;
public TestListViewAdapter(Context context, List<Object> objects) {
super(context, 0, objects);
}
#Override
public int getItemViewType(int position) {
switch (position) {
case 0:
return TYPE_HEADER;
default:
return TYPE_CELL;
}
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
switch (getItemViewType(position)) {
case TYPE_HEADER: {
convertView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.tools_list_item_card_big, parent, false);
}
break;
case TYPE_CELL: {
convertView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.tools_list_item_card_small, parent, false);
}
break;
}
}
return convertView;
}
}
in getview method of adapter switch case is used for inflating different views on listview row & getItemViewType() returns which view i want to use you can also check this by adding property in array list custom model.
I use https://github.com/bulletnoid/StaggeredGridView this library for make a pinterest style layout and use pulltorefresh on this layout. Also ı have a slide menu for choose different category and according to category which is user choose, refresh and refill the staggred again.
Pulltorefresh is work fine.
if user top of the layout and choose a category on slide menu it's work correctly. But if user bottom of the layout and choose a category on slide menu it's work not correctly .
the scenario, top of layout and select category on slidemenu and refill staggered layout. it's work correctly
the scenario, bottom of layout and select category on slidemenu and refill staggered layout. it's not work correctly
-->listviewAdapter
public void onItemClick(AdapterView<?> parent, View view, int position,
long arg3) {
// TODO Auto-generated method stub
switch (parent.getId()) {
case R.id.listView_sliding_menu:
smenu.toggle();
slidingMenuControl = true;
String categoryId = ((TextView) view.findViewById(R.id.categoryID))
.getText().toString();
parameters[0] = categoryId;
Toast.makeText(getApplicationContext(), categoryId,
Toast.LENGTH_LONG).show();
new PARSEJSONCATEGORYCONTENT().execute(parameters);
break;
default:
break;
}
}
-->parser
private class PARSEJSONCATEGORYCONTENT extends
AsyncTask<String[], Void, ArrayList<Utils>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
processDialoge();
}
protected ArrayList<Utils> doInBackground(String[]... params) {
String catId = params[0][0];
String startCount = params[0][5];
String count = params[0][6];
String urlCatContent = "http://212.58.8.109/webservice/api/content/cat/";
jArray = jsonParser.getJSONFromUrltoCategoryContent(urlCatContent,
Token, tokenValue, catId, startCount, count);
if (utilsArray == null) {
utilsArray = new ArrayList<Utils>();
} else if (slidingMenuControl == true) {
utilsArray.clear();
} else if (contentItemSelection != null) {
utilsArray.clear();
}
try {
// looping through All Contacts
for (int i = 0; i < jArray.length(); i++) {
JSONObject k = jArray.getJSONObject(i);
utils = new Utils();
// Storing each json item in variable
utils.imageUrl = k.getString("ipad_URL");
utils.imageWidth = k.getInt("ipad_width");
utils.imageHeight = k.getInt("ipad_height");
utils.categoryHeader = k.getString("contentHeader");
utils.contentDesc = k.getString("contentDesc");
utils.categoryContentId = k.getInt("id");
utils.contentTxt = k.getString("contentTxt");
Log.d("ipad_URL", utils.imageUrl);
utilsArray.add(utils);
}
String arrayLenght = Integer.toString(utilsArray.size());
Log.d("arrayLenght", arrayLenght);
} catch (JSONException e) {
e.printStackTrace();
}
return utilsArray;
}
protected void onPostExecute(ArrayList<Utils> utilsArray) {
staggeredAdapter.getMoreItemm(utilsArray);
// staggeredAdapter.setRefreshListener(false);
super.onPostExecute(utilsArray);
slidingMenuControl = false;
dialog.cancel();
}
}
-->BaseAdapter.java
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#SuppressLint("NewApi")
public class StaggeredAdapter extends BaseAdapter implements OnClickListener {
Typeface tf;
boolean refreshListener = false;
Utils utils;
private Context mContext;
private Application mAppContext;
private ArrayList<Utils> mUtilsArraylist = new ArrayList<Utils>();
public StaggeredAdapter(Context context, Application application) {
mContext = context;
mAppContext = application;
tf = Typeface.createFromAsset(mContext.getAssets(),
"font/Klavika-Medium.otf");
notifyDataSetChanged();
}
public void getMoreItemm(ArrayList<Utils> arrayList) {
mUtilsArraylist.clear();
mUtilsArraylist.addAll(arrayList);
this.notifyDataSetChanged();
}
public int getCount() {
return mUtilsArraylist == null ? 0 : mUtilsArraylist.size();
}
#Override
public Object getItem(int position) {
return mUtilsArraylist.get(position);
}
#Override
public long getItemId(int position) {
return mUtilsArraylist.indexOf(getItem(position));
}
#SuppressLint("NewApi")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
utils = mUtilsArraylist.get(position);
if (convertView == null) {
Holder holder = new Holder();
view = View.inflate(mContext, R.layout.staggered_item, null);
holder.imgUrl_content = (STGVImageView) view
.findViewById(R.id.imgUrl_content);
holder.tv_info = (TextView) view.findViewById(R.id.contentHeader);
holder.tv_info.setTypeface(tf);
holder.tv_info2 = (TextView) view.findViewById(R.id.contentDesc);
holder.tv_info2.setTypeface(tf);
view.setTag(holder);
} else {
return convertView;
}
final Holder holder = (Holder) view.getTag();
holder.imgUrl_content.mHeight = utils.imageHeight;
holder.imgUrl_content.mWidth = utils.imageWidth;
holder.imgUrl_content.setOnClickListener(this);
ImageLoader imgLoader = new ImageLoader(mAppContext);
imgLoader.DisplayImage(utils.imageUrl, holder.imgUrl_content);
holder.tv_info.setText(utils.categoryHeader);
holder.tv_info.setOnClickListener(this);
holder.tv_info2.setText(utils.contentDesc);
holder.tv_info2.setOnClickListener(this);
return view;
}
class Holder {
public STGVImageView imgUrl_content;
public TextView tv_info;
public TextView tv_info2;
}
public boolean isRefreshListener() {
return refreshListener;
}
public void setRefreshListener(boolean refreshListener) {
this.refreshListener = refreshListener;
}
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch (view.getId()) {
case R.id.imgUrl_content:
sendDataItemContentActivity();
break;
case R.id.contentHeader:
sendDataItemContentActivity();
break;
case R.id.contentDesc:
sendDataItemContentActivity();
break;
default:
break;
}
}
public void sendDataItemContentActivity() {
Intent intent = new Intent(mContext, ItemContent.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("contentTxt", utils.contentTxt);
intent.putExtra("contentHeader", utils.categoryHeader);
intent.putExtra("contentİmageUrl", utils.imageUrl);
intent.putExtra("contentCategoryName", utils.categoryName);
Bundle animBundle = ActivityOptions.makeCustomAnimation(mContext,
R.anim.anim, R.anim.anim2).toBundle();
mContext.startActivity(intent, animBundle);
}
}
I guess i had a same problem with using the same pinterest style library with you. i solve my problem by put this
#Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
mAdapter = new SearchSTGVAdapter(getActivity(), adsList, (Fragment)this);
ptrstgv.setAdapter(mAdapter);
}
which previously I put it in the onCreate method
For your information, I am implement this pinterest style in a view pager not a sliding menu
I am looking to build something similar to the settings UI of system android. I want something like a few checkboxpreferences, switchpreferences, edittextpreferences on the launch of application and then when user selects one preference open a fragment but i am just not able to figure that out.
I have referred Settings guide but it insists on using preference header. While displaying headers there is an unlikely overhead i am facing of displaying texts which in turn will load fragments.
For example,
My preference header is something like :
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- These settings headers are only used on tablets. -->
<header
android:fragment="${packageName}.${activityClass}$GeneralPreferenceFragment"
android:title="#string/pref_header_general" />
<header
android:fragment="${packageName}.${activityClass}$NotificationPreferenceFragment"
android:title="#string/pref_header_notifications" />
<header
android:fragment="${packageName}.${activityClass}$DataSyncPreferenceFragment"
android:title="#string/pref_header_data_sync" />
</preference-headers>
and just to load the actual data, i am having to use it. The actual data will have checkboxes and edittexts.
It would be great if someone gave some insights on this. It would be of great help if i could launch the actual fragment data on loading of screen. Better if i could have control of what fragment to call and call other fragments when a fragment item is selected.
To create custom preference headers, with switches and such, you need to extend PreferenceActivity with Headers as the Android docs describe and then override PreferenceActivity.setListAdapter to create your own list adapter, which creates the custom views. I made a pastebin with the code from the actual android settings activity to help you out. http://pastebin.com/RhSndGCQ
#Override
public void onBuildHeaders(List<Header> headers) {
loadHeadersFromResource(R.xml.settings_headers, headers);
updateHeaderList(headers);
}
#Override
public void setListAdapter(ListAdapter adapter) {
if (adapter == null) {
super.setListAdapter(null);
} else {
super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper));
}
}
private static class HeaderAdapter extends ArrayAdapter<Header> {
static final int HEADER_TYPE_CATEGORY = 0;
static final int HEADER_TYPE_NORMAL = 1;
static final int HEADER_TYPE_SWITCH = 2;
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_SWITCH + 1;
private final WifiEnabler mWifiEnabler;
private final BluetoothEnabler mBluetoothEnabler;
private final ProfileEnabler mProfileEnabler;
private AuthenticatorHelper mAuthHelper;
private static class HeaderViewHolder {
ImageView icon;
TextView title;
TextView summary;
Switch switch_;
}
private LayoutInflater mInflater;
static int getHeaderType(Header header) {
if (header.fragment == null && header.intent == null) {
return HEADER_TYPE_CATEGORY;
} else if (header.id == R.id.wifi_settings
|| header.id == R.id.bluetooth_settings
|| header.id == R.id.profiles_settings) {
return HEADER_TYPE_SWITCH;
} else {
return HEADER_TYPE_NORMAL;
}
}
#Override
public int getItemViewType(int position) {
Header header = getItem(position);
return getHeaderType(header);
}
#Override
public boolean areAllItemsEnabled() {
return false; // because of categories
}
#Override
public boolean isEnabled(int position) {
return getItemViewType(position) != HEADER_TYPE_CATEGORY;
}
#Override
public int getViewTypeCount() {
return HEADER_TYPE_COUNT;
}
#Override
public boolean hasStableIds() {
return true;
}
public HeaderAdapter(Context context, List<Header> objects,
AuthenticatorHelper authenticatorHelper) {
super(context, 0, objects);
mAuthHelper = authenticatorHelper;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Temp Switches provided as placeholder until the adapter replaces these with actual
// Switches inflated from their layouts. Must be done before adapter is set in super
mWifiEnabler = new WifiEnabler(context, new Switch(context));
mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
mProfileEnabler = new ProfileEnabler(context, null, new Switch(context));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
Header header = getItem(position);
int headerType = getHeaderType(header);
View view = null;
if (convertView == null || headerType == HEADER_TYPE_SWITCH) {
holder = new HeaderViewHolder();
switch (headerType) {
case HEADER_TYPE_CATEGORY:
view = new TextView(getContext(), null,
android.R.attr.listSeparatorTextViewStyle);
holder.title = (TextView) view;
break;
case HEADER_TYPE_SWITCH:
view = mInflater.inflate(R.layout.preference_header_switch_item, parent,
false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView)
view.findViewById(com.android.internal.R.id.title);
holder.summary = (TextView)
view.findViewById(com.android.internal.R.id.summary);
holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);
break;
case HEADER_TYPE_NORMAL:
view = mInflater.inflate(
R.layout.preference_header_item, parent,
false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView)
view.findViewById(com.android.internal.R.id.title);
holder.summary = (TextView)
view.findViewById(com.android.internal.R.id.summary);
break;
}
view.setTag(holder);
} else {
view = convertView;
holder = (HeaderViewHolder) view.getTag();
}
// All view fields must be updated every time, because the view may be recycled
switch (headerType) {
case HEADER_TYPE_CATEGORY:
holder.title.setText(header.getTitle(getContext().getResources()));
break;
case HEADER_TYPE_SWITCH:
// Would need a different treatment if the main menu had more switches
if (header.id == R.id.wifi_settings) {
mWifiEnabler.setSwitch(holder.switch_);
} else if (header.id == R.id.bluetooth_settings) {
mBluetoothEnabler.setSwitch(holder.switch_);
} else if (header.id == R.id.profiles_settings) {
mProfileEnabler.setSwitch(holder.switch_);
}
// No break, fall through on purpose to update common fields
//$FALL-THROUGH$
case HEADER_TYPE_NORMAL:
if (header.extras != null
&& header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
String accType = header.extras.getString(
ManageAccountsSettings.KEY_ACCOUNT_TYPE);
ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
lp.width = getContext().getResources().getDimensionPixelSize(
R.dimen.header_icon_width);
lp.height = lp.width;
holder.icon.setLayoutParams(lp);
Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
holder.icon.setImageDrawable(icon);
} else {
holder.icon.setImageResource(header.iconRes);
}
holder.title.setText(header.getTitle(getContext().getResources()));
CharSequence summary = header.getSummary(getContext().getResources());
if (!TextUtils.isEmpty(summary)) {
holder.summary.setVisibility(View.VISIBLE);
holder.summary.setText(summary);
} else {
holder.summary.setVisibility(View.GONE);
}
break;
}
return view;
}
public void resume() {
mWifiEnabler.resume();
mBluetoothEnabler.resume();
mProfileEnabler.resume();
}
public void pause() {
mWifiEnabler.pause();
mBluetoothEnabler.pause();
mProfileEnabler.pause();
}
}