I am trying to create a custom layout for list view in android studio. I was able to successfully get image in the in ListView on runtime but wasn't able to print text in the list view . When i run my program in emulator it runs without any error but it doesn't show any text it only shows image from drawables.
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
private final static String[] names={"A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A",
"A","A","A","A","A","A","A","A","A","A","A","A","A","A",};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView ls = findViewById((R.id.customlistview));
ls.setAdapter(new CustomListAdapter(getApplicationContext(),names,R.drawable.za));
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="#+id/customlistview"
android:layout_width="409dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
CustomListAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomListAdapter extends BaseAdapter {
private final Context context;
private final String[] names;
private final int image;
private final LayoutInflater layoutInflater;
public CustomListAdapter(Context context,String[] names,int image) {
this.context=context;
this.image=image;
this.names=names;
layoutInflater= (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return names.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rootview;
rootview = layoutInflater.inflate(R.layout.list_item_layout, null);
TextView tv= rootview.findViewById(R.id.textView);
ImageView iv=rootview.findViewById(R.id.imageView);
tv.setText(names[position]);
iv.setImageResource(image);
return rootview;
}
}
list_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:height="70dp"
android:gravity="center"
android:text="TextView"
android:textSize="18sp" />
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_weight="2"
app:srcCompat="#mipmap/ic_launcher" />
</LinearLayout>
The issue is in your list_item_layout file. There is an issue with match_parent in your layout try using below code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="3"
android:orientation="horizontal">
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:height="70dp"
android:gravity="center"
android:text="TextView"
android:textSize="18sp" />
<ImageView
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_weight="2"
app:srcCompat="#mipmap/ic_launcher" />
The problem was caused by the text colour , changing the colour of textview text in list_item_layout resolved the issue.
Related
I have a a persistent bottom sheet behavior in my main activity. The bottom sheet has a container for a fragment with a ViewPager2. The problem is that the ViewPager2 prevents the bottom sheet from vertically scrolling.
I recreated the issue in the a sample app. As you can see from this gif right here, the vertical scrolling doesn't work if it's inside the ViewPager2. Only when I drag all the way down outside the ViewPager2, does it start ducking the bottom sheet. This makes scrolling awkward.
I tried the solution described here but it didn't change anything. The activity's root view is a CoordinatorLayout and the fragment's root view is a LinearLayout with a ConstraintLayout around the ViewPager2.
Here's the main activity layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<Button
android:id="#+id/expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Expand Bottom Sheet" />
</LinearLayout>
<FrameLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true" />
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here's the fragment inside the bottom sheet's layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/purple_500">
<TextView
android:id="#+id/sheet_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:gravity="center_horizontal"
android:text="This is the sheet fragment"
android:textSize="24sp"
android:textAlignment="center"
android:textColor="#color/white" />
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="325dp"
android:layout_marginTop="75dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal"
android:text="Outside viewpager"
android:textSize="24sp"
android:textAlignment="center"
android:textColor="#color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/view_pager"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
Here's the MainActivity:
package com.example.myapplication;
import android.os.Bundle;
import android.widget.Button;
import android.widget.FrameLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomSheetBehavior<FrameLayout> bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));
bottomSheetBehavior.setPeekHeight(200);
bottomSheetBehavior.setHideable(true);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
Button expandButton = findViewById(R.id.expand_button);
expandButton.setOnClickListener(view -> bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED));
Fragment sheetFragment = new SheetFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, sheetFragment).commit();
}
}
And here's the SheetFragment:
package com.example.myapplication;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
public class SheetFragment extends Fragment {
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.fragment_sheet, container, false);
ViewPager2 viewPager = contentView.findViewById(R.id.view_pager);
ViewPagerAdapter adapter = new ViewPagerAdapter();
viewPager.setAdapter(adapter);
return contentView;
}
public class ViewPagerAdapter extends RecyclerView.Adapter<ViewPagerHolder> {
#NonNull
#Override
public ViewPagerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = getLayoutInflater().inflate(R.layout.pager_item, parent, false);
return new ViewPagerHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ViewPagerHolder holder, int position) {
holder.bind(position);
}
#Override
public int getItemCount() {
return 5;
}
}
private class ViewPagerHolder extends RecyclerView.ViewHolder {
public ViewPagerHolder(#NonNull View itemView) {
super(itemView);
}
public void bind(int number) {
TextView textView = itemView.findViewById(R.id.pager_textview);
textView.setText(String.format("Inside ViewPager\nPage #%d", number));
}
}
}
Thanks to the great bobekos for helping me with this. His answer was:
Thats because the bottomsheet allow only one scrollable view. So to make it work you must disable the nestedscrolling of the viewpager. The problem is you must
get access to the recylerview inside the viewpager2 there is currently
no get method and the class is final so you can't use inheritance. But
you can do this:
//as extension function
fun ViewPager2.disableNestedScrolling() {
(getChildAt(0) as? RecyclerView)?.apply {
isNestedScrollingEnabled = false
overScrollMode = View.OVER_SCROLL_NEVER
}
}
ps.not tested directly
I translated it to Java:
RecyclerView innerRecyclerView = (RecyclerView) viewPager2.getChildAt(0);
if (innerRecyclerView != null) {
innerRecyclerView.setNestedScrollingEnabled(false);
innerRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
}
Tested and works perfectly.
So here is my problem, I got an API that gives me the lastest news of many sources. Each one of them goes with a cardview. The problem here is, while I'm using the swipeRefresh, it gets duplicated cardViews with the same news, like if I have 10 news, it duplicates to 20 with the same ones.
Here is my code where I apply the swipeRefresh:
package com.example.newsapp4;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.newsapp4.Model.Articles;
import com.example.newsapp4.Model.Headlines;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class bbcnews extends AppCompatActivity {
Adapter adapter;
Intent intencion;
RecyclerView recyclerView;
public static String source = "My Source";
public static String API_KEY = "My API Key";
SwipeRefreshLayout srl;
List<Articles> articles = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bbcnews);
srl = findViewById(R.id.swipeRefresh);
srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
retrieveJson(source, API_KEY);
}
});
recyclerView = findViewById(R.id.recyclerView1);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new Adapter(bbcnews.this,articles);
recyclerView.setAdapter(adapter);
retrieveJson(source, API_KEY);
}
public void retrieveJson(String source, String apiKey){
srl.setRefreshing(true);
Call<Headlines> call = ApiClient.getInstance().getApi().getHeadlines(source, apiKey);
call.enqueue(new Callback<Headlines>() {
#Override
public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if(response.isSuccessful() && response.body().getArticles() != null){
srl.setRefreshing(false);
articles.clear();
articles = response.body().getArticles();
adapter.setArticles(articles);
}
}
#Override
public void onFailure(Call<Headlines> call, Throwable t) {
srl.setRefreshing(false);
Toast.makeText(bbcnews.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String getCountry(){
Locale locale = Locale.getDefault();
String country = locale.getCountry();
return country.toLowerCase();
}
public void aPerfil(View vista){
intencion = new Intent(this, profile_activity.class);
startActivity(intencion);
}
}
I don't think that I need to put the xml code with the progressbar and the swipeRefresh but here are both:
This one is the Items.xml where I created the cardView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:cardElevation="4dp"
android:id="#+id/cardView"
app:cardCornerRadius="10dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#+id/loader"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/image"
android:scaleType="centerCrop"
android:src="#drawable/img"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/gradient" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TITLE"
android:textSize="20dp"
android:padding="10dp"
android:fontFamily="#font/g_bold"
android:textColor="#color/white"
android:id="#+id/tvTitle"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Source"
android:textSize="16dp"
android:padding="10dp"
android:ems="15"
android:fontFamily="#font/g_light"
android:textColor="#color/white"
android:id="#+id/tvSource"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/g_light"
android:gravity="right"
android:text="Date"
android:textColor="#color/white"
android:padding="10dp"
android:textSize="16dp"
android:id="#+id/tvDate"/>
</LinearLayout>
</FrameLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
And here the one with the swipeRefresh in the recyclerView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/white"
tools:context=".bbcnews">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="DINGO BBC NEWS"
android:textColor="#color/black"
android:textSize="20sp"
android:fontFamily="#font/g_bold"
android:background="#color/white"
android:padding="10dp"
android:textAlignment="center"/>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:columnCount="2"
android:paddingLeft="20dp"
android:paddingRight="5dp"
android:background="#drawable/black_background"
android:rowCount="2">
<EditText
android:id="#+id/editTextTextPersonName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Search"
android:textColor="#color/grey"
android:textColorHint="#color/grey"
android:padding="5dp"
android:layout_column="0"
android:background="#drawable/black_background"
android:layout_row="0"
android:layout_columnWeight="1"
android:inputType="textPersonName" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="20dp"
android:background="#drawable/black_background"
android:drawableRight="#drawable/ic_baseline_search_24"
android:layout_column="1"
android:layout_row="0"/>
</GridLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipeRefresh">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:id="#+id/recyclerView1"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
Also this is my adapter.java code:
package com.example.newsapp4;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.newsapp4.Model.Articles;
import com.squareup.picasso.Picasso;
import java.util.List;
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
Context context;
List<Articles> articles;
public Adapter(Context context, List<Articles> articles) {
this.context = context;
this.articles = articles;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Articles a = articles.get(position);
String imageUrl = a.getUrlToImage();
holder.tvTitle.setText(a.getTitle());
holder.tvSource.setText(a.getSource().getName());
holder.tvDate.setText(a.getPublishedAt());
Picasso.with(context).load(imageUrl).into(holder.imageView);
}
#Override
public int getItemCount() {
return articles.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle,tvSource,tvDate;
ImageView imageView;
CardView cardView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvSource = itemView.findViewById(R.id.tvSource);
tvDate = itemView.findViewById(R.id.tvDate);
imageView = itemView.findViewById(R.id.image);
cardView = itemView.findViewById(R.id.cardView);
}
}
public void setArticles(List<Articles> articles) {
this.articles.addAll(articles);
int count = getItemCount();
notifyItemRangeInserted(count, count + articles.size());
}
}
Thanks for your time!
// Clear adapter list before add to list.
public void setArticles(List<Articles> articles) {
if(this.articles!=null && this.articles.size()>0)
this.articles.clear();
this.articles.addAll(articles);
int count = getItemCount();
notifyItemRangeInserted(count, count + articles.size());
}
From what I can understand in your code is on the success of API call after Swipe Refresh which is this section here
articles.clear();
articles = response.body().getArticles();
adapter.setArticles(articles);
You are here clearing the article inside your activity, but the thing is inside your Adapter there is already another list of articles, you are not clearing them.
And then when you make the adapter.setArticles(articles); call, inside the following function, your articles get added to the already existing list of articles and thus, the duplicate list.
public void setArticles(List<Articles> articles) {
this.articles.addAll(articles);
int count = getItemCount();
notifyItemRangeInserted(count, count + articles.size());
}
To fix this you can make the following modifications to your function.
public void setArticles(List<Articles> articles, boolean clearAll) {
if(clearAll){ this.articles.clear(); }
this.articles.addAll(articles);
notifyDataSetChanged();
}
And then modify your function call as follows
adapter.setArticles(articles, true);
That way when the Boolean is true, it will clear the existing list. Also I would suggest you to replace the insert call with data set change call. Else you can make a separate function all together for adding elements and for clearing existing elements.
I recently learned about Fragments in Android and was building a notepad application to practice them.
Idea: The idea behind the app is simple. I press the button to add a new note. A CardView Viewgroup turns visible. The fragment will be housed within this CardView.
Problem: When I press the button to add a new note, the fragment does not pop up.
MainActivity.java
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.util.Objects;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private CardView fragmentCardView;
private Button newNoteButton;
private FragmentManager fragmentManager = getSupportFragmentManager();
private FragmentTransaction fragmentTransaction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setActionBar();
newNoteButton = findViewById(R.id.new_note_button);
fragmentCardView = findViewById(R.id.fragment_cardView);
}
void setActionBar(){
Objects.requireNonNull(getSupportActionBar()).setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setCustomView(R.layout.layout_custom_action_bar);
}
void showCreateNoteFragment(){
CreateNoteFragment createNoteFragment = CreateNoteFragment.newInstance();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_cardView, createNoteFragment);
fragmentTransaction.commit();
fragmentCardView.setVisibility(View.VISIBLE);
}
#Override
public void onClick(View v) {
if (v == newNoteButton)
showCreateNoteFragment();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F2F2F2"
tools:context=".MainActivity">
<ListView
android:id="#+id/notes_listView"
android:layout_width="match_parent"
android:layout_height="667dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="#+id/new_note_button"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_marginTop="27dp"
android:fontFamily="#font/nunito_bold"
android:text="#string/new_note_button_string"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/notes_listView"/>
<androidx.cardview.widget.CardView
android:id="#+id/fragment_cardView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
android:layout_marginBottom="100dp"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:visibility="invisible"/>
</androidx.constraintlayout.widget.ConstraintLayout>
CreateNoteFragment.java
package com.example.notepadapplication;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class CreateNoteFragment extends Fragment implements View.OnClickListener {
private EditText inputEditText;
public CreateNoteFragment() {
// Required empty public constructor
}
static CreateNoteFragment newInstance(){
return new CreateNoteFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_create_note, container, false);
inputEditText = rootView.findViewById(R.id.input_editText);
Button saveButton = rootView.findViewById(R.id.save_button);
saveButton.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v) {
String saveButtonText = inputEditText.getText().toString();
}
}
fragment_create_note.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginTop="100dp"
android:layout_marginBottom="100dp"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="#F2F2F2"
tools:context=".CreateNoteFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/header_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="#string/display_fragment_header_string"
android:layout_marginTop="10dp"
android:textAlignment="center"
android:textSize="20sp"
android:fontFamily="#font/nunito_bold"/>
<View
android:id="#+id/divider_view"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:layout_below="#id/header_textView"
android:background="#000000" />
<EditText
android:id="#+id/input_editText"
android:layout_width="match_parent"
android:layout_height="475dp"
android:layout_below="#id/divider_view"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:padding="10dp"
android:inputType="textMultiLine"
android:gravity="top"
android:background="#FFFFFF"
tools:ignore="Autofill,LabelFor,TextFields" />
<Button
android:id="#+id/save_button"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:text="#string/save_button_string"
android:fontFamily="#font/nunito_bold"/>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Could anyone check why the fragment isn't popping up? Thanks for the help, guys.
P.S.: I think that the application might become a little bloated because of all the ViewGroups that I'm using. If you guys have a better way to design this, by all means, I would love any input.
When I press the button to add a new note, the fragment does not pop up.
This is expected since your button doesn't know what to do when pressed.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setActionBar();
newNoteButton = findViewById(R.id.new_note_button);
// Button will call activity's onClick whenever it's clicked
newNoteButton.setOnClickListener(this);
fragmentCardView = findViewById(R.id.fragment_cardView);
}
My Android app is composed of an SQLite database which populates individual ListView items with data user saves. Those items are available for display in activity_main.xml.
I have a class called RecordsListFragment which contains the two problematic methods: onItemClick and onItemLongClick. Here is the class in its entirety:
package com.example.benignfella.projectworkinghoursapplication.Fragment;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import com.example.benignfella.projectworkinghoursapplication.R;
import com.example.benignfella.projectworkinghoursapplication.Adapter.RecordsListAdapter;
import com.example.benignfella.projectworkinghoursapplication.Database.RecordsDAO;
import com.example.benignfella.projectworkinghoursapplication.GetSet.Records;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
public class RecordsListFragment extends Fragment implements OnItemClickListener, OnItemLongClickListener {
public static final String ARGUMENT_ITEM_ID = "records_list";
Activity activity;
ListView recordsListView;
ArrayList<Records> records;
RecordsListAdapter recordsListAdapter;
RecordsDAO recordsDAO;
private GetRecordsTask task;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = getActivity();
recordsDAO = new RecordsDAO(activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_records_list, container, false);
findViewsById(view);
task = new GetRecordsTask(activity);
task.execute((Void) null);
return view;
}
private void findViewsById(View view) {
recordsListView = (ListView) view.findViewById(R.id.list_records);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Records record = (Records) parent.getItemAtPosition(position);
if (records != null) {
Bundle arguments = new Bundle();
arguments.putParcelable("selectedRecord,", record);
CustomRecordsDialogFragment customRecordsDialogFragment = new CustomRecordsDialogFragment();
customRecordsDialogFragment.setArguments(arguments);
customRecordsDialogFragment.show(getFragmentManager(), CustomRecordsDialogFragment.ARGUMENT_ITEM_ID);
}
}
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Records records = (Records) parent.getItemAtPosition(position);
recordsDAO.deleteRecord(records);
recordsListAdapter.remove(records);
return true;
}
public class GetRecordsTask extends AsyncTask<Void, Void, ArrayList<Records>> {
private final WeakReference<Activity> activityWeakRef;
public GetRecordsTask(Activity context) {
this.activityWeakRef = new WeakReference<Activity>(context);
}
#Override
protected ArrayList<Records> doInBackground(Void... arg0) {
ArrayList<Records> recordsArrayList = recordsDAO.getRecords();
return recordsArrayList;
}
#Override
protected void onPostExecute(ArrayList<Records> empList) {
if (activityWeakRef.get() != null && !activityWeakRef.get().isFinishing()) {
records = empList;
if (empList != null) {
if (empList.size() != 0) {
recordsListAdapter = new RecordsListAdapter(activity, empList);
recordsListView.setAdapter(recordsListAdapter);
} else {
Toast.makeText(activity, "No Records about records... wait wot m8?",
Toast.LENGTH_LONG).show();
}
}
}
}
}
public void updateView() {
task = new GetRecordsTask(activity);
task.execute((Void) null);
}
public void onResume() {
getActivity().setTitle(R.string.app_name);
getActivity().getActionBar().setTitle(R.string.app_name);
super.onResume();
}
}
Here is activity_main.xml with FrameLayout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Layout resource file which contains a ListView is called fragment_records_list.xml and here it is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f9f9f9">
<ListView
android:id="#+id/list_records"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="10dp"
android:drawSelectorOnTop="true"
android:footerDividersEnabled="false"
android:padding="10dp"
android:scrollbarStyle="outsideOverlay"/>
</RelativeLayout>
Lastly, there is a resource file containing the layout of a single item, list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ededed"
android:descendantFocusability="blocksDescendants">
<RelativeLayout
android:id="#+id/layout_item"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_record_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="ID"
android:textSize="20dp"/>
<TextView
android:id="#+id/text_record_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/text_record_id"
android:padding="5dp"
android:text="Date"
android:textColor="#00942b"
android:textSize="20dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/text_record_date"
android:drawableStart="#drawable/ic_date_range_black_24dp"
android:padding="5dp"
/>
<TextView
android:id="#+id/text_record_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/text_record_id"
android:padding="5dp"
android:text="Description"
/>
<TextView
android:id="#+id/text_record_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/text_record_description"
android:padding="5dp"
android:text="17:00"
android:textSize="16dp"
android:textColor="#004561"
/>
<TextView
android:id="#+id/text_record_dash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/text_record_description"
android:layout_toRightOf="#id/text_record_start"
android:padding="5dp"
android:text="-"
android:textSize="16dp"
/>
<TextView
android:id="#+id/text_record_finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/text_record_description"
android:layout_toRightOf="#id/text_record_dash"
android:padding="5dp"
android:text="20:00"
android:textSize="16dp"
android:textColor="#c7002a"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_below="#id/text_record_description"
android:layout_toRightOf="#id/text_record_finish"
android:drawableStart="#drawable/ic_timer_black_24dp"
/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="#id/layout_item"
android:background="#000000"
/>
</RelativeLayout>
I haven't found a definite answer to my question, so I'm asking for a bit of help here.
You need set OnItemClickListener and OnLongItemClickListener to ListView, I edited your method in the initializing variable ListView:
private void findViewsById(View view) {
recordsListView = (ListView) view.findViewById(R.id.list_records);
recordsListView.setOnItemClickListener(this);
recordsListView.setOnItemLongClickListener(this);
}
I have made an android application, and its getting successfully compiled without any errors. But when I run app in my android phone, then it does not show the desired output.
This is my MainActivity.java:
package wahab.com.timetabledemo;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.support.v7.widget.Toolbar;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupUIViews();
initToolbar();
}
private void setupUIViews(){
toolbar = (Toolbar)findViewById(R.id.ToolbarMain);
listView = (ListView)findViewById(R.id.lvMain);
}
private void initToolbar(){
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("TimeTable App");
}
private void setupListView(){
String[] title = getResources().getStringArray(R.array.Main);
String[] description = getResources().getStringArray(R.array.Description);
SimpleAdaptor simpleAdaptor = new SimpleAdaptor(this, title, description);
listView.setAdapter(simpleAdaptor);
}
public class SimpleAdaptor extends BaseAdapter{
private Context mContext;
private LayoutInflater layoutInflater;
private TextView title, description;
private String[] titleArray;
private String[] descriptionArray;
private ImageView imageView;
public SimpleAdaptor(Context context, String[] title, String[] description){
mContext = context;
titleArray = title;
descriptionArray = description;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return titleArray.length;
}
#Override
public Object getItem(int i) {
return titleArray[i];
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null){
view = layoutInflater.inflate(R.layout.main_activity_single_item,null);
}
title = (TextView)view.findViewById(R.id.tvMain);
description = (TextView)view.findViewById(R.id.tvDescription);
imageView = (ImageView)view.findViewById((R.id.ivMain));
title.setText(titleArray[i]);
description.setText(descriptionArray[i]);
if(titleArray[i].equalsIgnoreCase("Timetable")){
imageView.setImageResource(R.drawable.timetable);
}
else if(titleArray[i].equalsIgnoreCase("Subjects")){
imageView.setImageResource(R.drawable.book);
}
else if(titleArray[i].equalsIgnoreCase("Faculty")){
imageView.setImageResource(R.drawable.contact);
}
else{
imageView.setImageResource(R.drawable.settings);
}
return view;
}
}
}
The given above is a error free code.
This is my activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="wahab.com.timetabledemo.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/ToolbarMain"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="#color/colorPrimary"
app:titleTextColor="#color/white">
</android.support.v7.widget.Toolbar>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lvMain"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:dividerHeight="10dp"
android:layout_below="#+id/ToolbarMain"
android:divider="#null">
</ListView>
</RelativeLayout>
In my activity_main.xml, I have used a RelativeLayout in which I have defined a Toolbar and a ListView. A ListView is defined so that I can add different list of operation.
This is my main_activity_single_item.xml:
<android.support.v7.widget.CardView android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#color/colorAccent"
android:elevation="4dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="80dp"
android:layout_height="105dp"
android:id="#+id/ivMain"
android:layout_marginLeft="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvMain"
android:textStyle="bold"
android:text="Timetable"
android:layout_marginTop="6dp"
android:layout_marginLeft="6dp"
android:layout_toRightOf="#+id/ivMain"
android:textSize="25sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvDescription"
android:text="description"
android:layout_marginLeft="6dp"
android:layout_marginTop="3dp"
android:layout_below="#+id/tvMain"
android:layout_toRightOf="#+id/ivMain"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvClick"
android:textSize="12sp"
android:text="click to know more"
android:layout_marginTop="6dp"
android:layout_alignParentRight="true"
android:layout_below="#+id/tvDescription"
android:layout_alignBottom="#+id/ivMain"/>
</RelativeLayout>
In this above xml file, I have created a CardView which will consist of an ImageView and 3 TextView, which is placed using a RelativeLayout.
So, my code is getting compiled properly and my app is also running but am not getting the desired output.
You need to call setupListView() in onCreate to display the list
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupUIViews();
initToolbar();
setupListView(); // to display list
^^^^^^^^^^
}