Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • Java for Android
  • Android Studio
  • Android Kotlin
  • Kotlin
  • Flutter
  • Dart
  • Android Project
  • Android Interview
Open In App
Next Article:
How to Share Image From URL with Intent in Android?
Next article icon

How to Display HTML in Textview along with Images in Android?

Last Updated : 27 Jul, 2022
Comments
Improve
Suggest changes
Like Article
Like
Report

There are some situations when one needs to display rich formatted text in the app, like for a blog app or an app like Quora but Android's inbuilt function doesn't allow to display inline images by default, moreover they show the ugly blue line to the left of anything inside blockquote tag. Here is the simple solution to show HTML in TextView along with images in Android. Note that we are going to implement this project using Kotlin language in Android. Below is a demo screenshot of the app.

demo

Prerequisites

  • Basic knowledge of the Coroutines library.
  • Basic knowledge of Picasso library.

Approach

Step 1: Create a new Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.

Step 2: Project setup before coding

  • Add some colors in the colors.xml file. The Colors here are for the blockquote Styling. You are free to choose different colors.
<?xml version="1.0" encoding="utf-8"?> <resources>     <color name="colorPrimary">#0F9D58</color>     <color name="colorPrimaryDark">#0F9D58</color>     <color name="colorAccent">#03DAC5</color>     <color name="Grey">#878585</color> </resources> 
  • Go to build.gradle(Module:app) file and add the following dependency.
    // Picasso library to downloading images   implementation 'com.squareup.picasso:picasso:2.71828'  // Coroutines dependency to put the downloading   process in background thread implementation   'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'    

Step 3: Working with activity_main.xml file

In the following activity_main.xml file we have added the following widgets:

  • EditText where the user will input the HTML text,
  • Button to trigger an event to display HTML text,
  • ScrollView for smooth scrolling,
  • TextView to display the HTML after processing the input.
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:padding="16dp"     tools:context=".MainActivity">       <!-- Edittext to take input for this sample app,           for real app you will not need this -->     <EditText         android:id="@+id/editor"         android:layout_width="0dp"         android:layout_height="40dp"         app:layout_constraintEnd_toStartOf="@+id/display_html"         app:layout_constraintHorizontal_bias="0.0"         app:layout_constraintStart_toStartOf="parent"         app:layout_constraintTop_toTopOf="parent" />      <!-- Button to trigger an event to display html/Rich text-->     <Button         android:id="@+id/display_html"         android:layout_width="100dp"         android:layout_height="50dp"         android:text="Display Html"         app:layout_constraintEnd_toEndOf="parent"         app:layout_constraintTop_toTopOf="parent" />      <!-- Scroll View for smooth scrolling -->     <ScrollView         android:layout_width="0dp"         android:layout_height="0dp"         android:layout_marginTop="16dp"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintEnd_toEndOf="parent"         app:layout_constraintStart_toStartOf="parent"         app:layout_constraintTop_toBottomOf="@+id/editor">          <!-- Text View in which you will display the html after               processing the input-->         <TextView             android:id="@+id/html_viewer"             android:layout_width="match_parent"             android:layout_height="match_parent">         </TextView>              </ScrollView>  </androidx.constraintlayout.widget.ConstraintLayout> 

Output UI:

Step 4: Create a Kotlin class ImageGetter.kt

Create a class that will download images contained in the img tag. Below is the complete ImageGetter.kt file. Understand the complete code by referring to the corresponding comments inside the code. 

ImageGetter.kt
import android.content.res.Resources import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.text.Html import android.widget.TextView import com.squareup.picasso.Picasso import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext  // Class to download Images which extends [Html.ImageGetter] class ImageGetter(     private val res: Resources,     private val htmlTextView: TextView ) : Html.ImageGetter {      // Function needs to overridden when extending [Html.ImageGetter] ,     // which will download the image     override fun getDrawable(url: String): Drawable {         val holder = BitmapDrawablePlaceHolder(res, null)          // Coroutine Scope to download image in Background         GlobalScope.launch(Dispatchers.IO) {             runCatching {                  // downloading image in bitmap format using [Picasso] Library                 val bitmap = Picasso.get().load(url).get()                 val drawable = BitmapDrawable(res, bitmap)                  // To make sure Images don't go out of screen , Setting width less                 // than screen width, You can change image size if you want                 val width = getScreenWidth() - 150                  // Images may stretch out if you will only resize width,                 // hence resize height to according to aspect ratio                 val aspectRatio: Float =                     (drawable.intrinsicWidth.toFloat()) / (drawable.intrinsicHeight.toFloat())                 val height = width / aspectRatio                 drawable.setBounds(10, 20, width, height.toInt())                 holder.setDrawable(drawable)                 holder.setBounds(10, 20, width, height.toInt())                 withContext(Dispatchers.Main) {                     htmlTextView.text = htmlTextView.text                 }             }         }         return holder     }      // Actually Putting images     internal class BitmapDrawablePlaceHolder(res: Resources, bitmap: Bitmap?) :         BitmapDrawable(res, bitmap) {         private var drawable: Drawable? = null          override fun draw(canvas: Canvas) {             drawable?.run { draw(canvas) }         }          fun setDrawable(drawable: Drawable) {             this.drawable = drawable         }     }      // Function to get screenWidth used above     fun getScreenWidth() =         Resources.getSystem().displayMetrics.widthPixels } 

Note: One can change the height and the width of the image according to your will in the getDrawable() function.

Step 5: Working with MainActivity.kt file

  • Create a click-Listener for the button inside the onCreate() method.
MainActivity.kt
class MainActivity : AppCompatActivity() {     override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)          // Click Listener to listener button click events.         // display_html is button id from activity_main.xml          // You don't need to get reference to it because kotlin          // provides synthetic import and          // We are gonna use for the same for rest of Views         display_html.setOnClickListener {             if (editor.text.isNotEmpty()) {                 displayHtml(editor.text.toString())             }         }     } } 
  • Create a function displayHtml() which you just called inside click listener.

Note: Kotlin has Synthetic import ,so there was no need of storing reference to views in a variable and we are going to do the same for all other views.

Kotlin
  private fun displayHtml(html: String) {              // Creating object of ImageGetter class you just created         val imageGetter = ImageGetter(resources, html_viewer)                 // Using Html framework to parse html         val styledText=HtmlCompat.fromHtml(html,                                             HtmlCompat.FROM_HTML_MODE_LEGACY,                                            imageGetter,null)                   // to enable image/link clicking         html_viewer.movementMethod = LinkMovementMethod.getInstance()                  // setting the text after formatting html and downloading and setting images         html_viewer.text = styledText     } 
  • So now the Image work is done, now it should load the images. Below is the complete code for the MainActivity.kt file.
Kotlin
import android.os.Bundle import android.text.method.LinkMovementMethod import androidx.appcompat.app.AppCompatActivity import androidx.core.text.HtmlCompat import kotlinx.android.synthetic.main.activity_main.*  class MainActivity : AppCompatActivity() {     override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)          // Click Listener to listener button click events.         // display_html is button id from activity_main.xml          // You don't need to get reference to it          // because kotlin provides synthetic import and          // We are gonna use for the same for rest of Views         display_html.setOnClickListener {             if (editor.text.isNotEmpty()) {                 displayHtml(editor.text.toString())             }         }     }      private fun displayHtml(html: String) {         // Creating object of ImageGetter class you just created         val imageGetter = ImageGetter(resources, html_viewer)          // Using Html framework to parse html         val styledText =             HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY, imageGetter,null)          // to enable image/link clicking         html_viewer.movementMethod = LinkMovementMethod.getInstance()          // setting the text after formatting html and downloading and setting images         html_viewer.text = styledText     } } 
  • Let's see how it's working now. Use HTML of another webpage. Here we have used the following webpage of the GFG article. Get the HTML string file from here.

Note: Remember that input the HTML text inside the EditText and then click on the "DISPLAY HTML" Button

Output

ouput screen

The images are now loading but you can see, for the blockquote part, there is the plain ugly blue line. We are now gonna fix that. 

Step 6: Create a Kotlin class QuoteSpanClass.kt

Create a Kotlin Class named QuoteSpanClass and add this following code to this file.

QuoteSpanClass.kt
import android.graphics.Canvas import android.graphics.Paint import android.text.Layout import android.text.style.LeadingMarginSpan import android.text.style.LineBackgroundSpan  class QuoteSpanClass(     private val backgroundColor: Int,     private val stripeColor: Int,     private val stripeWidth: Float,     private val gap: Float ) : LeadingMarginSpan, LineBackgroundSpan {          // Margin for the block quote tag     override fun getLeadingMargin(first: Boolean): Int {         return (stripeWidth + gap).toInt()     }      // this function draws the margin.     override fun drawLeadingMargin(         c: Canvas,         p: Paint,         x: Int,         dir: Int,         top: Int,         baseline: Int,         bottom: Int,         text: CharSequence,         start: Int,         end: Int,         first: Boolean,         layout: Layout     ) {          val style = p.style         val paintColor = p.color         p.style = Paint.Style.FILL         p.color = stripeColor          // Creating margin according to color and stripewidth it receives         // Press CTRL+Q on function name to read more         c.drawRect(x.toFloat(), top.toFloat(), x + dir * stripeWidth, bottom.toFloat(), p)         p.style = style         p.color = paintColor     }      override fun drawBackground(         c: Canvas,         p: Paint,         left: Int,         right: Int,         top: Int,         baseline: Int,         bottom: Int,         text: CharSequence,         start: Int,         end: Int,         lnum: Int     ) {         val paintColor = p.color         p.color = backgroundColor          // It draws the background on which blockquote text is written         c.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), p)         p.color = paintColor     } } 

Step 7: Working with MainActivity.kt file

  • Since the QuoteSpanClass is created, it's time to use this class in MainActivity.kt, but before you need to create a function to parse blockquote tags and draw the margin and background using the QuoteSpanClass.
MainActivity.kt
private fun replaceQuoteSpans(spannable: Spannable)  {   val quoteSpans: Array<QuoteSpan> =        spannable.getSpans(0, spannable.length - 1, QuoteSpan::class.java)    for (quoteSpan in quoteSpans)    {     val start: Int = spannable.getSpanStart(quoteSpan)     val end: Int = spannable.getSpanEnd(quoteSpan)     val flags: Int = spannable.getSpanFlags(quoteSpan)     spannable.removeSpan(quoteSpan)        spannable.setSpan(                QuoteSpanClass(                     // background color                     ContextCompat.getColor(this, R.color.colorPrimary),                       // strip color                     ContextCompat.getColor(this, R.color.colorAccent),                     // strip width                     10F, 50F                 ),                 start, end, flags             )         }      } 
  • And finally, call this function from displayHtml() function before setting the text for html_viewer. Below is the complete code for the MainActivity.kt file.
Kotlin
import android.os.Bundle import android.text.Spannable import android.text.method.LinkMovementMethod import android.text.style.QuoteSpan import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.text.HtmlCompat import kotlinx.android.synthetic.main.activity_main.*  class MainActivity : AppCompatActivity() {     override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)          // Click Listener to listener button click events.         // display_html is button id from activity_main.xml          // You don't need to get reference to it         // because kotlin provides synthetic import and         // We are gonna use for the same for rest of Views         display_html.setOnClickListener {             if (editor.text.isNotEmpty()) {                 displayHtml(editor.text.toString())             }         }     }      private fun displayHtml(html: String) {         // Creating object of ImageGetter class you just created         val imageGetter = ImageGetter(resources, html_viewer)          // Using Html framework to parse html         val styledText =             HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY, imageGetter,null)          replaceQuoteSpans(styledText as Spannable)          // setting the text after formatting html and downloading and setting images         html_viewer.text = styledText          // to enable image/link clicking         html_viewer.movementMethod = LinkMovementMethod.getInstance()      }      private fun replaceQuoteSpans(spannable: Spannable)     {         val quoteSpans: Array<QuoteSpan> =             spannable.getSpans(0, spannable.length - 1, QuoteSpan::class.java)          for (quoteSpan in quoteSpans)         {             val start: Int = spannable.getSpanStart(quoteSpan)             val end: Int = spannable.getSpanEnd(quoteSpan)             val flags: Int = spannable.getSpanFlags(quoteSpan)             spannable.removeSpan(quoteSpan)             spannable.setSpan(                 QuoteSpanClass(                     // background color                     ContextCompat.getColor(this, R.color.colorPrimary),                     // strip color                     ContextCompat.getColor(this, R.color.colorAccent),                     // strip width                     10F, 50F                 ),                 start, end, flags             )         }     } } 

Output

Now let's see the changes in the output screen.

output screen

Note: One can change strip Color, background color, strip width of your choice in replaceQuoteSpans function, and beautify it.

Step 8: Create a method ImageClick() in the MainActivity.kt file

  • But there is still one problem. What if you click an image? Nothing happens as of now. You need to add a few more lines to handle that.
Kotlin
// Function to parse image tags and enable click events fun ImageClick(html: Spannable)  {   for (span in html.getSpans(0, html.length, ImageSpan::class.java))   {     val flags = html.getSpanFlags(span)     val start = html.getSpanStart(span)     val end = html.getSpanEnd(span)     html.setSpan(object : URLSpan(span.source) {          override fun onClick(v: View) {                 Log.d(TAG, "onClick: url is ${span.source}")             }   }, start, end, flags) } 
  • And then call this function from displayHtml() Function before setting the text for html_viewer. Below is the complete code for the MainActivity.kt file. 
Kotlin
import android.os.Bundle import android.text.Spannable import android.text.method.LinkMovementMethod import android.text.style.ImageSpan import android.text.style.QuoteSpan import android.text.style.URLSpan import android.util.Log import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.text.HtmlCompat import kotlinx.android.synthetic.main.activity_main.*  private const val TAG="MainActivity"  class MainActivity : AppCompatActivity() {     override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)          // Click Listener to listener button click events.         // display_html is button id from activity_main.xml          // You don't need to get reference to it         // because kotlin provides synthetic import and         // We are gonna use for the same for rest of Views         display_html.setOnClickListener {             if (editor.text.isNotEmpty()) {                 displayHtml(editor.text.toString())             }         }     }      private fun displayHtml(html: String) {         // Creating object of ImageGetter class you just created         val imageGetter = ImageGetter(resources, html_viewer)          // Using Html framework to parse html         val styledText =             HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY, imageGetter, null)          replaceQuoteSpans(styledText as Spannable)         ImageClick(styledText as Spannable)          // setting the text after formatting html and downloading and setting images         html_viewer.text = styledText          // to enable image/link clicking         html_viewer.movementMethod = LinkMovementMethod.getInstance()      }      private fun replaceQuoteSpans(spannable: Spannable) {         val quoteSpans: Array<QuoteSpan> =             spannable.getSpans(0, spannable.length - 1, QuoteSpan::class.java)          for (quoteSpan in quoteSpans) {             val start: Int = spannable.getSpanStart(quoteSpan)             val end: Int = spannable.getSpanEnd(quoteSpan)             val flags: Int = spannable.getSpanFlags(quoteSpan)             spannable.removeSpan(quoteSpan)             spannable.setSpan(                 QuoteSpanClass(                     // background color                     ContextCompat.getColor(this, R.color.colorPrimary),                     // strip color                     ContextCompat.getColor(this, R.color.colorAccent),                     // strip width                     10F, 50F                 ),                 start, end, flags             )         }     }      // Function to parse image tags and enable click events     fun ImageClick(html: Spannable) {         for (span in html.getSpans(0, html.length, ImageSpan::class.java)) {             val flags = html.getSpanFlags(span)             val start = html.getSpanStart(span)             val end = html.getSpanEnd(span)             html.setSpan(object : URLSpan(span.source) {                 override fun onClick(v: View) {                     Log.d(TAG, "onClick: url is ${span.source}")                 }             }, start, end, flags)         }     } } 
  • Now if you click on any Image and check Logcat you will see the URL of the image is being logged. From there you can trigger some function with that URL.

Output: Run on Emulator

Resource: Get the complete project file here.


Next Article
How to Share Image From URL with Intent in Android?
author
sunny52525
Improve
Article Tags :
  • Kotlin
  • Android
  • Android Projects

Similar Reads

  • How to Add Hyperlink to TextView in Android?
    Hello geeks, today we are going to make an application where we will see that how we can add a link to a TextView in Android, and using this concept we will add portals - home and practice (of GeeksforGeeks) in our application. So that, user can directly go to these portals from our application. Wha
    3 min read
  • How to Add Text Drawable to ImageView in Android?
    In many android apps, you will get to see a feature in which you can see a simple text is displayed inside an ImageView or you can get to see that a text is displayed in a specific image or a shape. Mostly this type of view is seen in the Contacts application which is present on your Android device.
    5 min read
  • How to Add Images Directly to WhatsApp in Android?
    An image is a UI widget used to show images or upload images in an Android app. It is the sub-class of the View class. We can use it to add many images, like Bitmaps, and Drawable files. To use it a person can add ImageView to their XML files. Passing its id to the resource file. A sample video is g
    3 min read
  • How to Share Image From URL with Intent in Android?
    In this article, we will see how can we share images and text with Android Intent. In this activity URL of an image to be shared will be given with extra text and we will open the Dialog where the user chooses using which he wants to share this image as shown on the screen. A sample video is given b
    5 min read
  • How to Print Text Messages on Android Devices?
    Printing text messages from your Android device can be incredibly useful, whether you need to keep a record for legal purposes, save important conversations, or simply want a hard copy of your chats. This article will walk you through the steps to print text messages on Android devices. By following
    5 min read
  • How to Make Substring of a TextView Clickable in Android?
    In this article, we are going to implement a very important feature related to TextView. Here we are making part of a string or a substring to act as a substring. This feature is important while writing a blog because it may be possible that for certain points we want to redirect the user to a link.
    2 min read
  • TextView widget in Android with Examples
    Widget refers to the elements of the UI (User Interface) that help the user interact with the Android App. TextView is one of many such widgets which can be used to improve the UI of the app. TextView refers to the widget which displays some text on the screen based on the layout, size, colour, etc
    5 min read
  • How to Add a TextView with Rounded Corner in Android?
    TextView is an essential object of an Android application. It comes in the list of some basic objects of android and used to print text on the screen. In order to create better apps, we should learn that how can we create a TextView which have a background with rounded corners. We can implement this
    2 min read
  • How to Make an HTTP Request with Android?
    In any Android Application, there is only so much a user can do without an internet connection. All modern Android Applications interact with resources available online or a backend-specific to the app.  In this article, we will look at one of the ways through which we can retrieve and post resource
    6 min read
  • TextView in Android with Example
    TextView is a simple widget that is seen in every android application. This widget is used to display simple text within the android application. We can add custom styling to the text that we have to show. In this article, we will take a look at How to create a simple Text View in an android applica
    2 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences